2012-03-17 2 views
3

Я хочу прочитать строку с консоли.Прочитать строку произвольного размера из stdin?

Используя scanf или fgets, мне кажется, что только можно прочитать строку фиксированного максимального размера. Хуже того, кажется, что нет способа проверить, сколько символов было введено, если пользователь вводит слишком много (в этом случае я мог бы просто перераспределить массив, чтобы строка вписывалась в массив).

Я читал, что я должен читать по одному символу за один раз в ответ на this question, однако я не знаю, как читать один символ за раз, не нажимая кнопку пользователя после каждого символа.

Как я могу это сделать?

+1

Символы, которые вводит пользователь, буферизуются до тех пор, пока пользователь не нажимает кнопку ввода, но вы все равно можете их прочитать по одному. Чтение просто не начнется, пока пользователь не нажмет кнопку ввода. –

ответ

1

Попробуйте запустить это ..

#include <stdio.h> 

int main(){ 
    char next; 
    while((next=getchar())!=EOF) 
     printf("%c\n",next); 

} 

затем проверить страницу человека для GetChar(), чтобы увидеть, что на самом деле под рукой.

+0

Спасибо. Это самый простой ответ, который показал, что мне нужно для решения проблемы. – TravisG

+0

Должно быть 'int next', иначе вы не можете определить разницу между EOF и '\ xff' (или вы будете навсегда, если char без знака). – zaphod

1
char c = NULL; 
while (c != 0x0D) 
{ 
    scanf("%c", &c); 
    // do stuffs with c 
} 
4

ССАГПЗ документация says, что:

Standard C имеет функции, чтобы сделать это, но они не очень безопасны: пустые символы и даже (для gets) длинные строки могут запутать их. Таким образом, библиотека GNU обеспечивает нестандартную функцию getline, которая позволяет легко читать строки надежно.

и

[getline] является расширением GNU, но это рекомендуемый способ читать строки из потока. Альтернативные стандартные функции ненадежны.

Так что если вы используете GCC, я бы сказал, что вы должны использовать getline. Если вы не используете GCC, вы должны увидеть, обладает ли ваш компилятор аналогичной функцией. Если это не —, или если вы действительно предпочитаете использовать что-то стандартное —, тогда вам нужно прочитать по одному символу за раз.

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

Да, это так. Пользователь вводит последовательность символов, а затем нажимает Enter. Ваш первый вызов fgetc будет блокироваться до тех пор, пока пользователь не нажмет Enter, но после этого последующие вызовы fgetc будут немедленно возвращены, пока вы не прочтете новую строку. (Затем он будет блокироваться снова, пока пользователь не нажмет Enter снова.) Чтение «по одному символу за раз» не означает, что вы должны прочитать каждый символ до того, как пользователь наберет следующий; это просто означает, что, как только пользователь закончит вводить строку, вы читаете эту строку по одному символу за раз.

1

Вы можете использовать fgets() в цикле и перераспределить, если последний символ не является \n

/* UNTESTED: MAY HAVE OFF-BY-ONE ERRORS */ 
char *buffer; 
size_t bufsiz = 100; 
size_t buflen = 100; 
size_t bufcur = 0; 
buffer = malloc(bufsiz); 
for (;;) { 
    fgets(buffer + bufcur, bufsiz, stdin); 
    buflen = bufcur + strlen(buffer + bufcur); 
    if (buffer[buflen - 1] == '\n') break; 
    tmp = realloc(buffer, bufsiz * 2); 
    if (tmp == NULL) /* deal with error */; 
    buffer = tmp; 
    bufcur = buflen - 1; 
    bufsiz *= 2; 
} 
/* use buffer (and bufsiz and buflen) */ 
free(buffer); 
0

Принятая ответ следует отметить, что GetChar() возвращает Int. Тип данных char не достаточно большой, чтобы удерживать EOF.

Мы могли прочитать заданный объем текста и затем отбросить остальную часть ввода. Этот подход имеет больше, чем его доля критиков (как мы смеем предположить, что нужно отбрасывать). Другой вариант - использовать getline или написать пользовательскую функцию. Я думал, что попробую последний.

Это не мешает пользователям заполнять память большим файлом cat.

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <errno.h> 
#define MAX 50 
#define JUSTDO(a) if (!(a)) {perror(#a);exit(1);} 
/** char *get_line FILE *f 
* reads an arbitrarily long line of text or until EOF 
* caller must free the pointer returned after use 
*/ 
char *get_line (FILE *f) { 
    int len=MAX; 
    char buf[MAX],*e=NULL,*ret;JUSTDO (ret=calloc(MAX,1)); 
    while (fgets (buf,MAX,f)) { 
     if (len-strlen(ret)<MAX) JUSTDO (ret=realloc(ret,len*=2)); 
     strcat (ret,buf) ;if ((e=strrchr (ret,'\n'))) break; 
    } if (e) *e='\0'; 
    return ret; 
} 
/* main */ 
int main (void) { 
    char *s; 
    printf ("enter a line of text:\n"); 
    printf ("line was '%s'\n",s=get_line(stdin)) ;free (s); 
    return 0; 
} 
+0

Просто ... просто неправильно. http://linux.die.net/man/3/getchar. На странице руководства CLEARLY указывается функция fgetc(), getc() и getchar(), возвращающая символ, считанный как unsigned char, переданный в int или EOF в конце файла или ошибки. EOF, в то время как зависит от системы, обычно составляет -1 (или слово всех 1 бит). – FrankieTheKneeMan

Смежные вопросы