Hello Stackoverflow社区,我对此代码有疑问:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define MAX_SIZE 50
int main()
{
char *s = malloc(sizeof(char)*MAX_SIZE);
do{
int r = read(STDIN_FILENO, s, MAX_SIZE);
if(r==-1) printf("error");
else{
write(STDERR_FILENO, s, MAX_SIZE);
}
while(getchar()!='\n');
} while(strcmp(s,"end\n")!=0);
free(s);
return 0;
}
问题在于它产生了错误的输出,stdin在'do while'的每次迭代中都不会产生“干净”。我知道在Windows上我必须使用fflush(stdin)
但在互联网上观看我看到这个功能不适用于Linux。我使用linux,并且总是在互联网上观看我看到许多人说解决方案是while(getchar()!='\n);
而不是fflush(stdin)
,但问题没有得到解决......你能解释一下为什么吗?
答案 0 :(得分:1)
我看到的问题:
您将错误的参数传递给write
。而不是
write(STDERR_FILENO, s, MAX_SIZE);
应该是
write(STDERR_FILENO, s, r); // Write the number of characters that were read
// not MAX_SIZE
没有仔细考虑跳到行尾的策略。你有:
int r = read(STDIN_FILENO, s, MAX_SIZE);
if(r==-1) printf("error");
else{
write(STDERR_FILENO, s, MAX_SIZE);
}
while(getchar()!='\n');
首先,read
在遇到换行符时不会停止阅读。它最多可读取MAX_SIZE
个字符。它会在这个过程中吞噬尽可能多的换行符。您需要做的是改为使用fgets()
。
char* cp = fgets(s, MAX_SIZE, stdin);
if ( cp == NULL )
{
// If fgets fails, you probably reached the end of the file.
break;
}
fprintf(stderr, "%s", s);
该行
while(strcmp(s,"end\n")!=0);
如果使用read
从文件中读取数据,将导致未定义的行为,因为read
不会自动将终止空字符添加到s
。使用fgets
可以避免这个问题。
此外,由于您在编译时知道数组的大小,因此可以使用:
char s[MAX_SIZE];
而不是使用malloc
在运行时分配内存。