使用 fgets 从 C 中的文本文件读取:如果不是 \0 和 ,那是什么卡拉赫特



>编辑:如果他们有同样的问题,我会把问题留在这里供其他人阅读;我在评论中被告知解决方案是 line[strcspn(line,"\r")]= 0。在我的操作系统课程中,我从未被告知\r,因此您可能遇到了同样的问题,这可能对您有用。

所以我已经阅读了堆栈溢出上关于如何使用 fgets 从文本文件读取后摆脱 carachter 的所有内容。

在我的 C 文件中,我写了这个:

const char *ESCAPE= "1a2b3c4e5d";
FILE *FP= fopen(backup.txt);

假设这是我在备份中写的.txt: 1a2b3c4e5d 马克

如您所见,第一行实际上与 EESCAPE 相同,不是用于 carachter 吗?现在让我们看一下下面的代码,其中我尝试在文件中识别"1a2b3c4e5d",并在删除 carachter后,执行strcmp:

char line[64];
while(fgets(line, sizeof(line), FP)){
fprintf(stdout, "this is line lenght: %ld", strlen(line));
// It prints 12
line[strlen(line) -1]= 0; // Removing the new_line carachter;
fprintf(stdout, "This is line after getting rid of new_line: %ldn", strlen(line));
// It prints 11.
fprintf("This is ESCAPE lenght: %ldn", strlen(ESCAPE));
// It prints 10;
if(strcmp(line, ESCAPE) == 0){
fprintf(stdout, "I'm Heren");
}

fgets 的第一次读取将存储在"1a2b3c4e5d"行中,根据他的说法,长度为 12。现在,我读了 10 个卡拉奇和new_line一个,即 11,因为 strlen 不计算空终止符。我预计它是 11,因此第二次打印,在我删除 后,我预计长度为 10,而不是 11。

这意味着缓冲区内还有其他东西,但我真的不明白它是什么,当然,strcmp 永远不会是真的,因为这个可怕的第 11n 个卡拉奇特。你知道它是什么吗?我该如何解决它?谢谢!

我试图在Stackoverflow上寻找每一个答案。有些人甚至建议使用 strcspn,这是一个很好的发现(它甚至解决了缓冲区的一些令人不安的情况),但由于某种原因,代码在这种情况下不起作用。我找不到答案,因此我问了这个问题。

说来话长。简短的版本是,在Unix中,行以n结尾。在窗口中,它们被终止rn例如,请参阅此处。

更长的版本更复杂。现在作为一个"Unix爱好者讨厌Windows"的老极客,我应该告诉你Windows是错的,Unix是对的。但实际上,rn也是有道理的。从历史的角度来看。

所有这些都可以追溯到计算机输出是连接到打印机的串行线的时代。不是花哨的激光打印机,而更像是电子命令的打字机。 该打印机接收一堆字节(7 位字节,第 8 个用于奇偶校验),带有协议。41的意思是"打印A"。48 表示"打印 0"。这就是众所周知的ASCII码。 而这 128 个(再次是 7 位)数字中的一些,意味着"打印这个"以外的其他东西。 例如,7的意思是"敲钟"(就像微波一样,这样当它准备好时,有人会看到计算的结果:D)。 8 表示向后移动一个字符(例如,在先前打印的字符上打印其他内容)。等。 10的意思是(我说"意思"。但这一切仍然意味着这一点。只是想到当时非常脚踏实地的意义更有意义),往下走一行。和 13 "回到行的开头"。

因此,要在一行上打印"hello",然后在另一行上打印"world",您必须发送字节 104、101、108、108、111、13、10、119、111、114、108 100。意思是"打印h,e,l,l和o。然后将磁头送回行首(13),并将纸张向前送入1行(10)。并打印w o r l d。

n只是 C 中 10 的字符表示和 13 的r个字符表示(然后几乎在其他任何地方)。在 C 中,'n'10完全相同。一模一样0xA。只有 3 种不同的方式来表达完全相同的事情。

所以,现在,有些人可能(如在 unix 中)声称将纸张向前馈送 1 行意味着回到该新行(因此到目前为止是空的)行的开头。有些人可能会说(如在窗口中),如果您只是向前移动 1 行(跳过 13 行又名r),而不返回行首,您应该打印

hello
world

有些人甚至可能会说(就像Mac人曾经做过的那样,在他们成为Unix人的变种之前)r(转到行的开头)意味着向前馈送一行。

我不是很年轻(我离退休更接近于我职业生涯的开始),此外,我很小就开始编码(7 岁)。所以我编码已经40多年了。然而,我从来不知道输出是实际打印机的时间(我知道物理绿色终端,VT100 及其同类。但即使是那些也已经是某种打印机模拟器,没有实际执行移动和触发执行器的物理限制)。所以我不确定谁是真正正确的。我想这取决于打印机。但我知道,在我的机械打字机上,我曾经拥有(我认为大部分地方也是如此),向前送一行并回到起点的动作是以相同的手势完成的。虽然也可以分别处理这两件事。所以,我想他们没事。请注意,Windows(甚至MS-DOS)都不知道那个时间。但它继承了其他较旧的系统,例如 CP/M。

此外,我想对内存和磁盘使用情况的考虑也是为了说n而不是rn(曾几何时,这不会是一个荒谬的节俭。窗户从来都不以节俭而闻名...

所以,你看,这不是最近的辩论。它更像是一个"美国火车的宽度来自罗马马屁股的宽度"的故事。 但与此同时,在 2022 年,世界仍然分为换行符由 10 编码的系统(又名n)和由 13 编码然后由 10 编码的系统(又名rn)

相关内容

  • 没有找到相关文章

最新更新