【问题标题】:Why does fgetc function add a carriage return为什么fgetc函数要加回车
【发布时间】:2013-03-14 15:27:55
【问题描述】:

我正在读取一个由字符组成的 TXT 文件并将这些字符的 ASCII 值写入 output.txt。

每当我在 ASCII 表(换行)中读取字符编号 10 时,我在输出文件中得到 13 然后 10 而不是 10。 (13 表示 ASCII 回车)

这是我的代码:

 in_file = fopen(FILE_NAME, "rb");
...
  while((ch = fgetc(in_file)) != EOF){
    count++;
    fprintf(p, "%d\n", ch);
  }

谢谢

【问题讨论】:

    标签: c


    【解决方案1】:

    输入文件已使用 Windows 换行符格式化,即\r\n 的一对字符。 UNIX 文本文件只有\n。因此,您的输出是正确的。

    【讨论】:

    • @user2080006:要么你自己过滤掉\r。或者您使用外部工具,例如dos2unix。或者也以二进制模式打开输出文件,而不是文本模式...
    • 谢谢,但我在自动测试中使用了这个值。有办法将它解决到我的 .c 代码中吗?
    • 好吧,你还没有真正解释你实际上在做什么 - 似乎你读入一个文件,然后把它写到另一个文件中。您是要数行数,还是拆分它们或其他什么?另请说明您使用的是哪个平台。
    • 我尝试将 ASCII 字符转换为 ASCII 值,每一个新行我都使用 win。 XP 和 CODE BLOCKS 编译器
    • OK - 但在这种情况下,带有 Windows 换行符的 ASCII 文件的 正确 输出将在每一行的末尾为“13 10”。你是说你想禁止回车,即使它们在你的源文件中?
    【解决方案2】:

    第 10 个字符是换行符 (\n);字符 13 是回车符 (\r)。 Windows 行终止符通常是回车后跟换行符。在 UNIX/Linux 上,行终止符通常只是一个换行符。在 Mac OS 上,它曾经只是一个回车 IIRC,但在 OS X 上可能不再是这种情况(因为它是 UN*X 在引擎盖下)。

    如@jazzbassrob 所述,该文件可能是在 Windows 系统上创建的。
    或者,如果您在 Windows 系统上运行,我相信 I/O 库函数的某些实现会将 UNIX 风格的行终止符转换为 Windows 风格。

    因此,正如其他发帖人所指出的,输出可能是正确的。

    编辑:
    尝试从对fopen() 的调用中删除b;以二进制模式打开文件。在“文本”模式下——即fopen(FILE_NAME, "r")——fgetc()可能会丢弃回车。

    编辑 2: 在文本模式下,行终止符应该“规范化”为换行符(正如@DevSolar 指出的那样)。另一方面,如果您以二进制模式打开文件,则不应假设或依赖特定字符作为行终止符。 (除非您控制输入文件的创建,否则您特别关心从一种格式转换为另一种格式等)

    【讨论】:

    • C 标准将 \n 指定为行终止符。以文本模式打开文件应该使任何特定于平台的行终止符对应用程序透明。再说一遍,这就是理论。并且 OP 没有以文本模式打开输入文件(他也没有告诉我们他在哪个操作系统上运行)。
    • 最初我认为二进制标志是故意的。我意识到假设可能是错误的,并且在您发表评论时正在编辑我的回复;)
    • 如果我将模式从“rb”更改为“r”,当我收到 EOF 时循环中断
    • 不确定我是否理解评论。 EOF 不应该被视为常规字符——在特定操作系统上可能存在文件结尾字符,但你不应该假设是这种情况——这是一个条件(没有更多信息可从文件中读取)。
    【解决方案3】:

    您读取了回车符(0x0d),因为您以二进制模式读取文件"rb",这样 fgetc() 将读取每个字符,包括 0x0d 后跟 0x0a(回车符)。

    如果您以文本 "r" 的形式打开文件,fgetc() 将跳过 0x0d(如果后面跟着 0x0a)并仅显示 0x0a

    【讨论】:

    • 将输入文件作为文本打开只会在 Windows/DOS 系统上有所不同。 UNIX 系统将这两种模式视为相同...
    • 有没有一种方法可以在不使用二进制模式的情况下读取由字符组成的 txt 文件?我首先尝试过这个,但是任何时候 fgetc 收到 EOF 我的 while 循环都中断了
    • @user2080006:“任何时候”?当 fgetc() 到达文件末尾时,它应该恰好 一次 收到 EOF(文件结尾,-1) - 在这种情况下,您的循环 应该 结束.在这种情况下,二进制与文本模式不应该改变任何东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-18
    • 1970-01-01
    • 2020-11-25
    • 2013-08-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多