Getline 和 FGETS 在第一次尝试时无法获取输入

  • 本文关键字:获取 FGETS 第一次 Getline c
  • 更新时间 :
  • 英文 :

void someFunction(){
char *buffer;
size_t bufsize = 32;
int bytes_read;
for (;;) {
buffer = (char *) malloc(bufsize * sizeof(char));
if (buffer == NULL) {
perror("Unable to allocate buffer");
exit(1);
}
FILE *ptr;
ptr = fopen("sample.txt", "a");
printf("Enter Stuff to write down:n");
//getline(&buffer,&bufsize,stdin);
//fgets(buffer, 30, stdin);
//scanf("%[^n]%*c", buffer);
//scanf("%s", buffer);
if (buffer[0] == '0') {
break;
}
WriteWithFprintf(ptr, buffer);
free(buffer);
fclose(ptr);
}
}

问题是:如果我使用

getline(&buffer,&bufsize,stdin);

fgets(buffer, 30, stdin);

然后它像这样转义第一个:

Enter Stuff to write down:
Enter Stuff to write down:
0

如果我使用:

scanf("%[^n]%*c", buffer);

然后我得到一个无限循环。

它确实适用于:

scanf("%s", buffer);

但我想要有空间的输入,所以这对我来说不是一个选择。

针对代码的不同变体描述的所有行为都与可从换行符读取的下一个字符一致,stdin换行符(大概是从前一行输入中读取)。

在这种情况下,

  • getline()fgets()替代项会将换行符(以及任何前面的字符)读取为一行,然后在第二遍循环中循环读取您实际想要的行。
  • 由于%[^n]字段的匹配失败,第一个scanf()变体将不读取任何内容(%[指令不会跳过前导空格)。 没有匹配任何东西,就不会尝试将任何东西与%*c相匹配。
  • 第二种scanf()替代方法将按照您的描述工作,因为scanf在处理%s指令(包括任何换行符)时将自动使用前导空格。

您可以执行多种操作,具体取决于确切地想要如何处理输入。 这是其中之一:

int c = fgetc(stdin);
if (c == EOF) {
// handle eof ...
} else if (c != 'n') {
ungetc(c, stdin);
}
// your choice for reading the wanted data ...

这将消耗最多一个来自stdin的前导换行符来摆脱您的障碍。

getline 和 fget 在第一次尝试时无法获得输入

两者都没有失败。 两人都只是读了一'n',然后立即返回。 这个'n'是以前的输入函数(如scanf("%s", ...))遗留下来的,它不消耗整getline()不是标准 C 库的一部分。

scanf("%[^n]%*c", buffer);'n'第一个可用字符时无法读取任何内容。

scanf("%s", buffer);会消耗所有可选的前导空格,例如'n'。 这似乎适用于 OP。

scanf("%[^n]%*c", buffer);scanf("%s", buffer);都是糟糕的代码,因为它们没有宽度限制,有缓冲区溢出的风险。


我建议学习者根本不使用scanf(),并使用fgets()执行所有输入,包括未发布的部分代码。

最新更新