2

标准 C 中的文件输入函数,如 fgetc()、fgets() 或 fscanf(),是否对 NUL ('\0') 字符有任何问题,或者将它们与其他字符区别对待?

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

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

4

3 回答 3

2

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

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

于 2012-10-13T23:56:36.397 回答
1

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

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

于 2012-10-13T23:10:17.603 回答
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';

于 2012-10-13T23:38:29.827 回答