C的文件I / O函数如何处理NUL字符?

时间:2012-10-13 23:03:22

标签: c

标准C中的文件输入函数,如fgetc(),fgets()或fscanf(),对NUL('\ 0')字符有任何问题,或者对待它们的方式与其他字符不同?

我打算问我是否可以使用fgets()来读取可能包含NUL字符的行,但我刚才意识到,因为该函数NUL-终止输入并且不以任何其他方式返回长度,无论如何它都毫无价值。

我可以使用fgetc()/ getc()/ getchar()吗?

3 个答案:

答案 0 :(得分:2)

如果您正在阅读的内容实际上是文本,那么您处于某种尴尬的境地。 fgets会很好地读取NUL,将它们存储在缓冲区中,然后继续训练。问题是,你只是读了不再是NTBS(NUL- 终止字节串)的内容,正如C库通常所期望的那样,所以大多数期望字符串的函数都会忽略第一个NUL。并且你真的没有可靠的方法来获得长度,因为fgets没有返回给你,strlen期望一个C字符串。 (你可以想象每次都将缓冲区清零并查找最后一个非NUL字符以获得长度,但对于大缓冲区中的短字符串,这有点难看。)

如果你正在处理二进制文件,事情要简单得多。您只需freadfwrite数据,一切顺利。但是如果你想要带有NUL的文本,你可能最终需要你自己的read-a-line函数来返回长度。

答案 1 :(得分:1)

如果以“TEXT”模式打开文件,则无法读取NULL字符以外的文件。但是二进制文件可以是open()ed,read()和close()d。查找这些函数和二进制i / o。

此外,EOF字符被设置为TEXT文件中的NULL字符。但是,您可以使用fstat查询二进制文件的大小,并读取二进制数据(可能包含NULL字符)

答案 2 :(得分:0)

不,输入函数不会对NUL的处理方式与其他字符不同。因为任何返回未知数量的字符的人都使用NUL终止,但最简单的方法是编写自己的,例如:

ssize_t myfgets(char *buffer, size_t buffSize, FILE *file) {
    ssize_t count = 0;
    int character;
    while(count < buffSize && (character = getc(file)) != EOF) {
        buffer[count] = character;
        ++count;
        if(character == '\n') break;
    }
    if(count == 0 && character == EOF) return EOF;
    return count;
}

此函数与fgets类似,不同之处在于它返回读取的字符数,而不是NUL终止字符串。如果您希望字符串以NUL终止,请将while循环中的第一个条件更改为count < buffSize-1,并在循环后添加buffer[count] = '\0';