c - 为什么我需要按两次 Ctrl-D 来标记文件结束?

标签 c eof getchar

char **query; 
query = (char**) malloc ( sizeof(char*) );

int f=0;
int i=0,j=0,c;


while((c=getchar())!=EOF)
{      
    if(!isalpha(c))
        continue;

    if(f==1)
        query=(char**) realloc(query,(i+1)*sizeof(char*));

    query[i]=(char*) malloc(sizeof(char));
    query[i][j]=c;
    j++;


    while( (c=getchar())!=EOF&&c!=' '&&c!='\t' )
    {      

        query[i]=(char*) realloc(query[i],(j+1)*sizeof(char));

        query[i][j]=c;
        ++j;
    }   

    query[i][j]='\0';
    printf("%s\n",query[i]);
    if(c==EOF){

        break;
    }   

   ++i;
   f=1;
   j=0;
}

我希望上面的代码片段读取一行由空格和制表符分隔的字符串,直到一个 EOF,但它需要 2 个 EOF 才能结束循环。此外,字符串只能包含字母字符。

我挣扎了大约 2 天。 请提供一些反馈。

编辑:最有可能的原因是我在写完最后一个字符串而不是回车键后按了 CTRL+D 键,但现在我按了 Enter,然后按了 CTRL+D,它按预期工作。 但是,我怎样才能将它更改为在我在最后一个字符串后按 CTRL+D 后完成?

最佳答案

在类 Unix 系统上(至少在默认情况下),通过在行首键入 Ctrl-D 触发文件结束条件如果您不在行首,请按 Ctrl-D 两次

在后一种情况下,您阅读的最后一行不会有 '\n'在它的末尾;您可能需要考虑到这一点。

这由 POSIX/The Open Group Base Specifications Issue 7 在 section 11 中指定(而不是间接指定) ,特别是 11.1.9:

EOF
Special character on input, which is recognized if the ICANON flag is set. When received, all the bytes waiting to be read are immediately passed to the process without waiting for a <newline>, and the EOF is discarded. Thus, if there are no bytes waiting (that is, the EOF occurred at the beginning of a line), a byte count of zero shall be returned from the read(), representing an end-of-file indication. If ICANON is set, the EOF character shall be discarded when processed.

POSIX read()函数通过返回零字节计数向其调用者指示文件结束(或错误)条件,指示没有更多字节的数据可读取。 (C 的 <stdio> 在 POSIX 系统上建立在 read() 和其他 POSIX 特定函数之上。)

EOF(不要与 C 宏 EOF 混淆)默认映射到 Ctrl-D。在行首键入 EOF 字符(在输入的最开头或紧接在换行符之后)会立即触发文件结束条件。在行首之外键入 EOF 字符会导致该行上的先前数据立即由下一个 read() 返回。要求足够字节的调用; 再次 键入 EOF 字符会做同样的事情,但在这种情况下,没有剩余的字节要读取,并且会触发文件结束条件。一行中间的单个 EOF 字符被丢弃(如果设置了 ICANON,通常是这样)。

关于c - 为什么我需要按两次 Ctrl-D 来标记文件结束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21260674/

相关文章:

c - 如何创建一个 TCP 服务器-客户端程序,将 200 个 tcp 流从源发送到目的地?

c - c 中的 scanf 和关系输入缓冲区

bash - 语法错误 : unexpected end of file when editing code within here documents with emacs. 使用 nano 工作正常

在不使用 c99 标准的情况下使用 bool 编译 c 代码

c++ - 将 DBF 转换为 JSON

c++ - GCC 可以使用读-修改-写指令来更新 volatile 变量吗?

C++ eof() 问题 - 永远不会返回 true?

C 段错误,即使使用 EOF

混淆缓冲区和 EOF 和 getchar

c - 在c上使用getchar()在输入后得到 'Enter'