使用fseek回溯

时间:2009-04-23 04:21:26

标签: c file-io fseek

使用fseek回溯字符fscanf操作是否可靠?

例如,如果我只有fscanf - 10个字符,但我想回溯10个字符,我可以fseek(infile, -10, SEEK_CUR)吗?

对于大多数情况,它可以工作,但我似乎遇到了字符^M的问题。显然fseek将其注册为char,但fscanf没有注册它,因此在我之前的示例中,包含^M的10个char块需要fseek(infile, -11, SEEK_CUR)fseek(infile, -10, SEEK_CUR)会缩短1个字符。

为什么会这样?

编辑:我在文字模式下使用fopen

5 个答案:

答案 0 :(得分:8)

您正在看到“文本”和“二进制”文件之间的区别。当以文本模式打开文件时(fopen第二个参数中没有'b'),stdio库可能(实际上必须)根据操作系统对文本文件的约定来解释文件的内容。例如,在Windows中,一行以\ r \ n结尾,并且由stdio将其转换为单个\ n,因为这是C约定。写入文本文件时,单个\ n输出为\ r \ n。

这使得编写处理文本文件的可移植C程序变得更加容易。然而,一些细节变得复杂,而fseeking就是其中之一。因此,在一些情况下,C标准仅在文本文件中定义fseek:从最开始,到最后,到当前位置,以及用ftell检索的先前位置。换句话说,您无法计算要搜索文本文件的位置。或者你可以,但你必须自己处理所有平台特定的细节。

或者,您可以使用二进制文件并自行进行行结束转换。再次,可移植性受到影响。

在你的情况下,如果你只想回到你上次fscancf的地方,最简单的就是在fscanf之前使用ftell。

答案 1 :(得分:2)

这是因为fseek使用字节,而fscanf智能地处理回车符和换行符是两个字节,并将它们作为一个字符吞并。

答案 2 :(得分:1)

Fseek不了解文件的内容,只是将文件指针移回10个字符。

fscanf取决于操作系统,可以不同地解释换行符;如果你在DOS上并且^ M没有出现在文件中,fscanf甚至可能会插入^ M.查看C编译器附带的手册

答案 3 :(得分:1)

刚刚尝试使用VS2008,发现fscanf和fseek以相同的方式处理CR和LF字符(作为单个字符)。

所以有两个文件:

<00> 0000000:3132 3334 3554 3738 3930 3132 3334 3536 12345X7890123456

0000000:3132 3334 350d 0a37 3839 3031 3233 3435 12345..789012345

如果我读了15个字符,我会到第二个'5',然后找回10个字符,我的下一个字符读取是第一个案例中的'X'和第二个中的CRLF。

这似乎是一个特定于操作系统/编译器的问题。

答案 4 :(得分:0)

您是否测试过fscanf的返回值?发布一些代码。

看看ungetc。你可能需要对它进行循环。