使用 fgetc 读取换行符但在 macOS 中出错
use fgetc reading newline character but error in macOS
我的代码需要用到很多fgetc(inp)
.
在windows下没有问题,但在macOS下程序会报错
我发现问题是由于两个系统的换行符字符数不一致导致的:
macOS 只是 \n
,windows 是 \r\n
所以我创建了一个新函数来替换 fgetc(inp)
读取换行符
void getwhite() {
int white = fgetc(inp);
if (isspace(white) == 0) {
fseek(inp, -1, SEEK_CUR);
}
}
但是没有按预期工作,在 windows 中仍然工作正常,macOS 仍然报错
您应该使用 ungetc()
而不是 fseek()
来推回从流中读取的字节:
int getwhite() {
int c = fgetc(inp);
if (!isspace(c)) {
ungetc(c, inp);
}
return c;
}
关于 windows 和其他系统上的行尾处理:由于遗留原因,windows 仍然使用 CR LR 序列来指示文本文件中的行尾,C 库翻译这些序列透明地 到单个 '\n'
字节,用于将文件作为文本读取的程序,使用 fopen()
或更低级别的 open()
接口。
这使得文件偏移量难以使用,因为从文件中读取的字节数可能与文件中的字节偏移量不同,而标准函数无法检索到:long
ftell()
对于以文本模式打开的流,仅作为要传递给 fseek()
对于以文本模式打开的同一文件的 SEEK_SET
模式的数字才有意义。在文本流上的 SEEK_CUR
和 SEEK_END
模式下使用非零偏移量进行搜索具有未定义的行为,如 C 标准中所指定:
7.21.9.2 The fseek
function
Synopsis
#include
int fseek(FILE *stream, long int offset, int whence);
Description
[...]
For a text stream, either offset
shall be zero, or offset
shall be a value returned by an earlier successful call to the ftell
function on a stream associated with the same file and whence
shall be SEEK_SET
.
如果您需要依赖文件偏移量,您应该以二进制模式打开文件并在您自己的代码中明确处理行结尾。
Apple 操作系统曾经将行尾表示为单个 CR 字节,但在 10 多年前采用了 Mach unix 兼容内核时切换为单个 NL 字节。
我的代码需要用到很多fgetc(inp)
.
在windows下没有问题,但在macOS下程序会报错
我发现问题是由于两个系统的换行符字符数不一致导致的:
macOS 只是 \n
,windows 是 \r\n
所以我创建了一个新函数来替换 fgetc(inp)
读取换行符
void getwhite() {
int white = fgetc(inp);
if (isspace(white) == 0) {
fseek(inp, -1, SEEK_CUR);
}
}
但是没有按预期工作,在 windows 中仍然工作正常,macOS 仍然报错
您应该使用 ungetc()
而不是 fseek()
来推回从流中读取的字节:
int getwhite() {
int c = fgetc(inp);
if (!isspace(c)) {
ungetc(c, inp);
}
return c;
}
关于 windows 和其他系统上的行尾处理:由于遗留原因,windows 仍然使用 CR LR 序列来指示文本文件中的行尾,C 库翻译这些序列透明地 到单个 '\n'
字节,用于将文件作为文本读取的程序,使用 fopen()
或更低级别的 open()
接口。
这使得文件偏移量难以使用,因为从文件中读取的字节数可能与文件中的字节偏移量不同,而标准函数无法检索到:long
ftell()
对于以文本模式打开的流,仅作为要传递给 fseek()
对于以文本模式打开的同一文件的 SEEK_SET
模式的数字才有意义。在文本流上的 SEEK_CUR
和 SEEK_END
模式下使用非零偏移量进行搜索具有未定义的行为,如 C 标准中所指定:
7.21.9.2 The
fseek
function
Synopsis#include int fseek(FILE *stream, long int offset, int whence);
Description
[...]For a text stream, either
offset
shall be zero, oroffset
shall be a value returned by an earlier successful call to theftell
function on a stream associated with the same file andwhence
shall beSEEK_SET
.
如果您需要依赖文件偏移量,您应该以二进制模式打开文件并在您自己的代码中明确处理行结尾。
Apple 操作系统曾经将行尾表示为单个 CR 字节,但在 10 多年前采用了 Mach unix 兼容内核时切换为单个 NL 字节。