2012-03-17 33 views
3

我想从控制台读取一个字符串。从标准输入读取任意大小的字符串?

然而,使用scanf或者fgets,在我看来,它只能读取固定最大大小的字符串。更糟糕的是,似乎没有办法检查用户输入太多情况下输入的字符数(在这种情况下,我可以简单地重新分配数组,以使字符串适合数组)。

我读过我应该在this question的回答中一次读出一个字符,但是我不知道如何一次读取一个字符,而不必让用户在每个字符后按回车。

我该怎么办?

+1

用户输入的字符会被缓冲,直到用户按下回车键,但您仍然可以一次读取一个字符。直到用户按下回车键,读数才会开始。 – 2012-03-17 14:59:59

回答

1

尝试运行这个..

#include <stdio.h> 

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

} 

然后检查手册页的getchar(),看看手头什么是真正的。

+0

谢谢。这是最简单的答案,证明我需要解决问题。 – TravisG 2012-03-17 16:00:36

+0

应该是'int next',否则你不能分辨EOF和'\ xff'之间的区别(或者如果char是无符号的,你将永远循环)。 – zaphod 2016-02-25 01:06:28

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

GCC的文档says说:

标准C具有的功能要做到这一点,但他们也不是很安全:空字符,甚至(对gets)长行可以迷惑他们。所以GNU库提供了非标准的getline函数,可以很容易地可靠地读取行。

[getline]是GNU扩展,但它是读取从流线的推荐方法。替代标准功能不可靠。

所以如果你使用GCC,我会说你应该使用getline。如果你不使用GCC,你应该看看你的编译器是否提供了类似的功能。如果它不是—或者如果你真的喜欢使用标准—,那么你需要一次读取一个字符。

我不知道如何一次读取一个字符,而不需要用户在每个字符后按回车。

是的,你这样做。用户输入一系列字符,然后按Enter键。您的第一个fgetc呼叫将阻止,直到用户按下Enter键,但在此之后,后续的fgetc呼叫将立即返回,直到您阅读换行符。 (然后它会再次阻止,直到用户再次按Enter。)一次读取“一个字符”并不意味着您必须在用户键入下一个字符之前阅读每个字符;它只是意味着,一旦用户输入完一行,就可以一次读取该行的一个字符。

1

您可以使用一个循环和realloc 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 large_file填充内存。

#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()将读取的字符作为无符号字符转换为文件或错误结尾处的int或EOF。依赖于系统的EOF通常是-1(或全1位的字)。 – FrankieTheKneeMan 2012-08-10 16:43:43