Удаление нескольких пробелов с помощью putchar и getchar в C

Задача: Напишите программу, которая получает текстовый ввод с помощью getchar() и выводит строку, удалив кратные пробелы.

Вот как я написал псевдокод:

While each input character is received before reaching EOF, do the following:
     1) if character is non-blank, print it out
     2) otherwise:
         a. print out the blank
         b. do nothing untill the next non-blank character 
     3) if a non-blank character is reached, go back to 1)

Я попытался реализовать алгоритм как таковой:

#include <stdio.h>
/* replaces multiple blanks with a single blank */
main(){
    char c;
    while((c= getchar())!=EOF){
        if (c != ' ')
            putchar(c);
        else {
            putchar(c);
            while(c == ' ')
                ;
        }
    }   
}

Когда строка содержит пробелы, она останавливается. Я не уверен, как я должен его отлаживать. Я думаю, что проблема с моим вторым while, и программа входит в бесконечный цикл, а не ждет новых символов.


person Omid    schedule 29.11.2014    source источник
comment
while(c == ' ') ; - бесконечный цикл. обновить c.   -  person BLUEPIXY    schedule 29.11.2014


Ответы (4)


#include <stdio.h>
/* replaces multiple blanks with a single blank */
main(){
    int c; // thanx chux
    while((c= getchar())!=EOF){
        if (c != ' ')
            putchar(c);
        else {
            putchar(c);
            while((c= getchar())!=EOF)
                if (c!=' ')
                {
                    putchar(c);
                    break;
                }
        }
    }   
}

Ваше последнее время не читало символы из стандартного ввода, вызывая бесконечный цикл, сравнивающий последний красный символ с предыдущим getchar().

person Anonymous    schedule 29.11.2014
comment
NMDV, но используйте int c, чтобы EOF отличался от всех 256 различных char. - person chux - Reinstate Monica; 29.11.2014
comment
main() -> int main(void) . также добавьте return 0; для хорошего стиля. - person chqrlie; 16.07.2017

Анонимный ответ работает, но есть гораздо более простой алгоритм, который также работает:

While there is input remaining:
    Read a character.
    If the current and previous characters aren't both blank:
        Print the current character.

In C:

#include <stdio.h>

int main() {
    int prev = EOF, c;
    while ((c = getchar()) != EOF) {
        if (c != ' ' || prev != ' ')
            putchar(c);
        prev = c;
    }
    return 0;
}
person hobbs    schedule 29.11.2014
comment
Это работает не совсем так, как я хочу. Я ввел I am here to learn. и получил I m ere o earn. - person Omid; 29.11.2014

В вашей программе есть несколько проблем:

  • прототип для main() должен включать возвращаемый тип int.

  • c должен быть определен как int, чтобы вы могли правильно отличить EOF от всех допустимых значений байтов, возвращаемых getchar().

  • после того, как вы определите пустой символ, вы должны продолжить чтение символов и пропустить последующие пробелы.

  • технически пустые символы включают пробел ' ' и символ табуляции '\t'. Вы должны использовать isblank() из <ctype.h> и изменить свою программу, чтобы пропускать последующие пустые символы.

Вот модифицированная версия:

#include <ctype.h>
#include <stdio.h>

/* replaces multiple blanks with a single blank */
int main(void) {
    int c;
    while ((c = getchar()) != EOF) {
        putchar(c);
        if (isblank(c)) {
            while (isblank(c = getchar())
                continue;
            if (c == EOF)
                break;
            putchar(c);
        }
    }
    return 0;
}
person chqrlie    schedule 15.07.2017

Это сработало для меня.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int c;
    int space = 0;

    while ((c = getchar())!= EOF){

            if (c != ' '){
                putchar(c);
            }else{
                if(space == ' '){
                    continue;
                }else{
                    putchar(c);
                }
            }
            space = c;
    }
    return 0;
}
person ARMAND MARTINIUC    schedule 15.07.2017