Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 从标准输入读取任意大小的字符串?_C - Fatal编程技术网

C 从标准输入读取任意大小的字符串?

C 从标准输入读取任意大小的字符串?,c,C,我想从控制台读取字符串 然而,在我看来,使用scanf或fgets只能读取固定最大大小的字符串。更糟糕的是,似乎没有办法检查输入了多少字符,以防用户输入太多(在这种情况下,我可以简单地重新定位数组,以使字符串适合数组) 我在回答中读到我应该一次读一个字符,但是我不知道如何一次读一个字符,而不让用户在每个字符后按enter键 我该怎么做?GCC文档: char c = NULL; while (c != 0x0D) { scanf("%c", &c); // do stuf

我想从控制台读取字符串

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

我在回答中读到我应该一次读一个字符,但是我不知道如何一次读一个字符,而不让用户在每个字符后按enter键

我该怎么做?

GCC文档:

char c = NULL;
while (c != 0x0D)
{
    scanf("%c", &c);
    // do stuffs with c
}
标准C有这样做的函数,但它们不是很安全:空字符甚至(对于
get
)长行都会混淆它们。因此,GNU库提供了非标准的
getline
函数,可以轻松可靠地读取行

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

因此,如果您使用的是GCC,我建议您应该使用
getline
。如果您没有使用GCC,您应该看看您的编译器是否提供了类似的功能。如果没有,或者如果你真的喜欢使用标准的东西,那么你需要一次读一个字符

我不知道如何在不让用户在每个字符后按enter键的情况下一次读取一个字符

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

尝试运行此功能

#include <stdio.h>

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

}
#包括
int main(){
下一步;
while((next=getchar())!=EOF)
printf(“%c\n”,下一步);
}
然后查看getchar()的手册页,看看手头真正有什么。

如果最后一个字符不是
\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);

接受的答案应该注意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;
} 
#包括
#包括
#包括
#包括
#定义最大值50
#定义JUSTDO(a)if(!(a)){perror(#a);exit(1);}
/**char*get_行文件*f
*读取任意长的文本行或直到EOF
*调用方必须释放使用后返回的指针
*/
char*get_行(文件*f){
int len=最大值;
char buf[MAX],*e=NULL,*ret;JUSTDO(ret=calloc(MAX,1));
while(fgets(buf、MAX、f)){

如果(len strlen(ret)用户输入的字符在用户按enter键之前会被缓冲,但您仍然可以一次读取一个字符。在用户按enter键之前,读取不会开始。谢谢。这是演示我需要解决问题的最简单答案。下一步应为
int
,否则您无法分辨两者之间的区别een EOF和'\xff'(或者如果字符是无符号的,您将永远循环)。只是…只是错误。.手册页清楚地说明了fgetc()、getc()和getchar()将读取为无符号字符的字符在文件或错误末尾转换为int或EOF。EOF虽然依赖于系统,但通常为-1(或所有1位的字)。