Can';使用STDIN在fgetc()缓冲区中找不到EOF
编辑Can';使用STDIN在fgetc()缓冲区中找不到EOF,c,eof,fgetc,C,Eof,Fgetc,编辑 问题的解决办法是理解Ctrl-D实际上在做什么。 在新的空行上,单个Ctrl-D将发出EOF信号。 但是,如果行中已经有字符,则第一个Ctrl-D会使行的内容回显到屏幕上(但不会写入STDOUT)。当缓冲区中已经有字符时,必须发出第二个Ctrl-D来发送信号EOF,从而将缓冲区写入STDOUT 这可以通过将输出重定向到文件来演示。 编辑 我正在使用fgetc()从stdin读取输入。我循环直到收到EOF。在循环中,我根据按下Ctrl-D之前键入的字符构建了一个字符串。但我无法找到退出循环的
问题的解决办法是理解Ctrl-D实际上在做什么。
在新的空行上,单个Ctrl-D将发出EOF信号。
但是,如果行中已经有字符,则第一个Ctrl-D会使行的内容回显到屏幕上(但不会写入
STDOUT
)。当缓冲区中已经有字符时,必须发出第二个Ctrl-D来发送信号EOF
,从而将缓冲区写入STDOUT
这可以通过将输出重定向到文件来演示。
编辑 我正在使用fgetc()从
stdin
读取输入。我循环直到收到EOF。在循环中,我根据按下Ctrl-D之前键入的字符构建了一个字符串。但我无法找到退出循环的方法,因为从中读取的缓冲区ch=fgetc()不包含EOF。(EOF仅触发fgetc()返回其第一个值。)
ungect()不允许将EOF推入缓冲区,推入任何其他字符都有可能与真实数据混淆,我被卡住了!!我已经阅读了很多答案,但它们没有解决这个问题,或者不适用于我试图实现的用例
我想能够计数,偷看,在标准输入缓冲区等
我真的不想读整行(或一次读X个字符),因为我正在处理从fgetc()到达(编辑)的每个字符
有没有关于如何克服这一困境的建议?(不使用NCurses)
我在用Ubuntu。EOF=Ctrl-D
以下是我正在使用的一些代码:
这与Jonathan的简单示例相同,但不是我想要的:
int main(int argc, char **argv) {
int inputChr;
do {
inputChr = fgetc(stdin);
if (inputChr != EOF) {
fputc( inputChr, stdout);
}
if (feof(stdin)) {
if (ferror(stdin)) {
perror(NULL);
return errno;
}
}
} while (inputChr != EOF);
return EXIT_SUCCESS;
}
但是,这会被卡住,但正在尝试执行我想要的操作(编辑),但第二次需要Ctrl-D:
char *buildLine (FILE *inputSource, char *currLine, int showTabs, int showNonPrint, int *haveLF) {
int inputChr;
char *thisLine = malloc(1);
int inputSize;
*haveLF = FALSE;
while ( (inputChr = fgetc(inputSource)) != EOF ) {
if (ferror(inputSource)) {
perror(NULL);
} else {
if (inputChr == LF) {
*haveLF = TRUE;
} else {
thisLine = strconcat(thisLine,(char *)&inputChr);
}
}
}
return thisLine;
}
还有一些被问及的代码:
char * strconcat ( char *str1, char * str2) {
char *newStr = malloc(strlen(str1)+strlen(str2)+1);
if (newStr == NULL) {
return NULL;
}
strcpy(newStr,str1);
strcat(newStr,str2);
return newStr;
}
下面的版本逐个字符处理输入字符,其工作原理与cat
类似。但我决定先将每个字符处理成一行,然后再应用一些需要实现的额外转换。这简化了状态机设计,但可能尝试构建行不是好的选择(不使用NCurses)(
int-echoint(文件*inputSource,文件*outputDestination,整数编号,整数显示端){
int haveNewLine=TRUE;
int lineNo=1;
int-inputChr;
做{
inputChr=fgetc(inputSource);
if(inputChr!=EOF){
if(编号和换行符(&H){
long lineNoSize=(long)log10(lineNo)+1;//有效楼层(log10(lineNo)+1)=数字
char*lineNoStr=(lineNoSizeEOF
通常是一个整数(不是char
),并且它与任何有效字符的值都不相同
正常的C风格是终止用\0
构建的字符串。当然,理论上可以读取NUL
字符,如果您想处理这些可能性,您需要记录读取的字符数以及它们被读入的缓冲区。必须有其他变化这个问题的答案已经足够好了,但这里还有一个
fgetc()
(和getc()
和getchar()
)返回的值是int
,而不是char
。它必须是int
,因为可以返回的值集包括char
的所有可能值和一个额外的值EOF,即负值虽然EOF通常是-1
,但您不应该按照该假设编码
有两件事可能会出问题:
char c;
while ((c = fgetc(stdin)) != EOF)
如果类型char
是有符号的,则某些字符(通常为0xFF,通常为ÿ,y-umlaut,Unicode U+00FF,带分音符的拉丁小写字母y)将被误解为在达到EOF之前指示EOF
如果类型char
是无符号的,则您将永远不会检测到EOF,因为分配给c
的值将是0xFF(正值),并且该值将永远不会与EOF(负值)进行比较
使用ungect()
无法将EOF推回输入流,这是正确的
请注意,Control-D(或Windows上的Control-Z)不会向输入队列中添加字符。相反,它表示没有更多可用字符(稍微简化了一些事情),这意味着read()
系统调用返回0字节读取,这意味着EOF
使用getchar()
和putchar()
将标准输入复制到标准输出的一个简单程序是:
int c;
while ((c = getchar()) != EOF)
putchar(c);
您可以将其调整为使用fgetc()
或getc()
和fputc()
或putc()
如果您希望打开文件并读取这些文件。关键点是使用int
来保存读取的值。您使用的是哪个操作系统?如果要检查ch
是否为int
,请确保int
是EOF
。通常在Linux中,键入一些字符后按Ctrl-D会刷新输入流(这样您的程序就可以开始读取它了)但不会结束输入。再次按它,或在换行符后直接按它,会导致流结束。@MattMcNabb:setvbuf
是标准C的一部分,如果stdin
是FIFO,它将完美地工作。例如,在Unix系统中,如果stdin
是tty,它至少不会工作,但这两者都不是必需的C标准也不禁止;不是因为stdin是行缓冲的,而是因为默认情况下,tty设备本身在输入ENTER或某些其他特殊字符之前不会向userland返回任何内容。OK;您需要在malloc()后面加一个*thisLine='\0';
在调用代码中;否则,您的读取超出了范围。您也像筛子一样泄漏;您需要释放(str1);
在strconcat()中。
同样,如果内存分配失败
int c;
while ((c = getchar()) != EOF)
putchar(c);