提问人:petyr 提问时间:1/28/2023 最后编辑:Steve Friedlpetyr 更新时间:1/28/2023 访问量:82
为什么在我使用 CTRL+D 退出循环后不等待我输入字符串
Why doesn't it wait for me to input string after I exit the loop using CTRL+D
问:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char c, char_array[100];
int i = 0;
printf("Enter characters (press CTRL+D to end):\n");
while(fgets(char_array+i,sizeof(char_array)-i,stdin)) {
i = i + strlen(char_array+i);
if(char_array[i-1] == EOF)
break;
}
char_array[i-1] = '\0';
strtok(char_array,"\n");
printf("\nEnter a string:\n");
char string[100];
fgets(string,sizeof(string),stdin);
printf("\nCharacter Array: %s\n", char_array);
printf("String: %s\n", string);
return 0;
}
这是代码,我尝试了许多不同的变体(更简单),但它总是有同样的问题......我输入字符,按 CTRL+D,它结束,无需等待我输入字符串。请帮忙
我尽了我所能,但我就是做不到它,我的朋友也做不到......我有和考试,我需要在最多 3 天内完成,所以我需要我能得到的所有帮助。
答:
0赞
Allan Wind
1/28/2023
#1
fgets()
在流关闭时返回。在 Linux 上,如果终端缓冲区不为空,则 Ctrl-D 将刷新终端缓冲区(但不会返回,因为它保持行缓冲状态),并且需要第二个 Ctrl-D 来触发流的 EOF 状态。NULL
fgets()
如果数组已满,您还希望终止循环,否则它是一个无限循环:
#define ARRAY_LEN 100
//...
while(i < ARRAY_LEN - 1 && fgets(char_array + i, ARRAY_LEN - i,stdin)) {
fgets()
不会作为正在读取的字符串的一部分发出,所以这是不正确的,并且由于 stdin 是行缓冲的,如果缓冲区已满,则最后一个字符是 either 或 any,如果最后一个字符被读取,这可能是 or (无论字符是否带符号,但这仍然是错误的):EOF
\n
-1
0xff
if(char_array[i-1] == EOF)
break;
- 下一行:
char_array[i-1] = '\0';
如果数组已满(即数据丢失),则删除最后一个字符,即我们最后读取的任何字符(即数据丢失)。\n
- 当输入流处于状态时,第二个将返回 NULL。您可以在调用之前清除该状态以获取第二个字符串。如果流确实结束了,如 ,当然,第 2 个返回 NULL 再次。
EOF
fgets()
clearerr(stdin)
fgets()
echo "hello world" | ./your_program
fgets()
我建议你用一个空行来表示输入的结束:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ARRAY_LEN 100
int main() {
printf("Enter characters (empty line to end):\n");
char char_array[ARRAY_LEN];
for(size_t i = 0; i < ARRAY_LEN - 1; i += strlen(char_array)) {
if(!fgets(char_array + i, ARRAY_LEN - i, stdin)) {
printf("fgets() failed\n");
return 1;
}
if(char_array[i] == '\n') {
char_array[i] = '\0';
break;
}
}
strtok(char_array, "\n");
printf("Enter a string:\n");
char string[ARRAY_LEN];
char *rv = fgets(string,sizeof(string),stdin);
printf("Character Array: %s\n", char_array);
printf("String: %s\n", string);
}
和示例会话:
Enter characters (empty line to end):
hello
world
Enter a string:
friend
Character Array: hello
String: friend
评论
0赞
Dúthomhas
1/28/2023
每个人系统上的 EOF 都是 ,但重要的一点是,它是一个大于有效输入的可用范围的位值。A 可以是有符号的,也可以是无符号的,但返回的有效值将始终为最大值 0..255(设置了 8 位),其中设置了所有位。-1
char
getchar()
-1
0赞
Allan Wind
1/28/2023
@Dúthomhas 谢谢。我调整了 EOF 和 -1 的答案。什么将 EOF 定义为 -1?除了 7.4 之外,我在 C 标准中没有看到它“也不能表示为无符号字符”。没错,因此理论上用户可以输入0xff编码的任何内容并进行比较等于 EOF,但我指出这不会发生。我们不是在谈论 getchar(),而是在谈论 fgets(),即 chars。
1赞
Chris Dodd
1/28/2023
@AllanWind,stdio.h 头文件将 EOF 定义为 -1。标准 (7.21.1) 仅指定它是一个宏,可扩展为类型为负数的值。int
1赞
Peter - Reinstate Monica
1/28/2023
@ChrisDodd 您的 stdio.h 将其定义为 -1 ;-)。
1赞
Dúthomhas
1/28/2023
根据 POSIX,EOF 可以是任何负数。 只是最简单的目标,我不知道有任何系统不是它 - 但我从来不需要关心或验证,因为重点是在返回值中设置了高位,而有效的字符输入不能设置这些位。-1
0赞
Chris Dodd
1/28/2023
#2
对于 stdio 流,error/eof 是粘性的 -- 也就是说,一旦发生错误或 eof 条件,对 的进一步操作将继续返回 EOF 或 NULL (取决于函数),而不是尝试进一步读取或写入任何内容。FILE *
要重置 上的 eof 状态,您需要调用 。完成此操作后,您可以从终端读取其他输入。FILE *
clearerr(stdin)
评论
if(char_array[i-1] == EOF)
EOF
fgets()
NULL
EOF
fgets
if(char_array[i-1] == EOF)
是不正确的。 通常是从某些例程(如 )返回的值。 不放入缓冲区。EOF
int
getchar
fgets
EOF
char_array
fgets