Как прочитать поток символов, длина которых неизвестна из стандартного ввода в c

Я хочу прочитать поток символов из стандартного ввода, длина которого неизвестна. Я пытаюсь читать посимвольно как

#include <stdio.h>
int main(void) 
{
    char ch;
    do 
    {
        scanf("%c",&ch);
        //do some comparison of ch
    }while(ch!='');
return 0;
}

Помогите мне написать условие, чтобы я мог правильно читать ввод, не входя в бесконечный цикл

Пример ввода:

abcdefghijklmnop

person Balakrishna Avulapati    schedule 17.09.2015    source источник
comment
Вы имеете в виду, как хранить прочитанный вами файл неизвестного размера в памяти? Потому что читать вроде легко. Чтение посимвольно неэффективно (и лучше делать с getchar). Если вы не хотите вводить ограничения по размеру, я считаю, что было бы лучше создать связанный список, выделить часть памяти, читать до тех пор, пока она не будет заполнена, а затем связать новую часть, пока файл не будет готов.   -  person Amadan    schedule 17.09.2015
comment
Что вы считаете концом вашего входного потока? Возврат кареты? Что-то другое?   -  person Renaud Pacalet    schedule 17.09.2015
comment
@Amadan Дело не в файлах   -  person Balakrishna Avulapati    schedule 17.09.2015
comment
Потоки. То же самое. (На самом деле это не одно и то же, с файлом вы бы знали размер, поэтому то, что я описываю, не понадобится.) Если ваш поток не завершается; в этом случае вы должны хорошо подумать, что вы считаете моментом, когда вы можете перестать слушать. Если вы всегда должны продолжать слушать, разветвите свой процесс или оторвите нить.   -  person Amadan    schedule 17.09.2015
comment
Если вы должны использовать scanf, вы можете проверить его возвращаемое значение - поскольку у него есть 1 совпадение, он вернет 1 в случае успеха и ‹1 в случае EOF или ошибки. Вы также можете использовать feof(stdin) и ferror(stdin) - как в while ( ( 0 == feof(stdin) ) && (0 == ferror(stdin) ) )   -  person Sigve Kolbeinson    schedule 17.09.2015
comment
Спасибо @Sigve Kolbeinson. Ваш комментарий именно то, что я искал. Для меня возвращаемое значение будет работать, я думаю   -  person Balakrishna Avulapati    schedule 17.09.2015


Ответы (2)


Вероятно, простейшая форма решения будет такой

#include <stdio.h>
int main(void) 
{
    char ch;
    do 
    {
        ch = fgetc(stdin); 
        //do some comparison of ch
    }while( ch != EOF );

return 0;
}

Но, сказав это, постановка задачи, как показано ниже

прочитать поток символов из стандартного ввода, длина которого неизвестна

немного сложно. Что касается приведенной выше программы, вы, вероятно, можете остановить ее с помощью ctrl + d, EOF или запустить двоичный файл с перенаправлением файла.

./a.out < input.txt

на самом деле именно интерпретация стандартного ввода делает этот вопрос более осмысленным.

person Potato    schedule 17.09.2015
comment
У меня нет прав на использование файлов, и даже я не хочу их использовать. И я не могу использовать что-то вроде ctrl+d. будет ли EOF работать для стандартного ввода? - person Balakrishna Avulapati; 17.09.2015
comment
как вы закончите свою программу? - person Potato; 17.09.2015
comment
Спасибо @kkk, я попробовал комбинацию EOF и getchar(). это сработало. Можете ли вы помочь мне воспроизвести ту же функциональность с помощью scanf? - person Balakrishna Avulapati; 17.09.2015
comment
проверьте это хорошее чтение, чтобы принять решение о случае репликации с помощью scanf vs-scanf и этот stackoverflow.com/questions/2482634/ - person Potato; 17.09.2015
comment
@BalakrishnaAvulapati Этот код по существу правильный, за исключением того факта, что ch должен быть объявлен как int. Причина этого в том, что EOF определяется как –1, а 0xff может быть допустимым байтом. - person JeremyP; 17.09.2015
comment
@JeremyP Думаю, да, но когда вы используете getchar() , он неявно считывает его как целое число. поэтому у меня сработала комбинация EOF и getchar(). Спасибо - person Balakrishna Avulapati; 17.09.2015
comment
@BalakrishnaAvulapati да, он явно читает его как целое число, но ch - это символ, поэтому он сразу отбрасывает все байты, кроме наименее значимого. Поверьте мне, вы должны объявить ch как int. - person JeremyP; 17.09.2015

Ваш escape-символ неверен. Хотите написать все в одну строку? Затем используйте '\n', чтобы завершить цикл.

while (ch != '\n')

Если вы пишете символ за символом, используйте один для выхода из последовательности (например, '@')

while (ch != '@')
person Neverover    schedule 17.09.2015
comment
Спасибо за ответ, но у меня нет разрешения на собственный выходной персонаж. У меня просто есть поток символов, длина которых неизвестна, и я хочу читать символы один за другим, чтобы их обработка для моего сценария была проще. - person Balakrishna Avulapati; 17.09.2015
comment
Когда вы говорите один за другим, вы имеете в виду, что вы напишете первый символ, затем введите, затем второй символ, затем введите ...? Или вы пишете все, потом вводите, но просто читаете их по одному? Если это второе использование '\n'. - person Neverover; 17.09.2015