c++:Istream 将 .txt 文件中的每个换行符计为两个

c++: Istream counts every newline in a .txt file as two

我有一个小问题。似乎出于某种原因,我的函数在计算 .txt 文件的大小时计算换行符,因为它是两个字符而不是一个。这是函数:

#define IN_FILE "in_mat.txt"    

#define IN_BUF
#ifdef IN_BUF
void inBuf(char *(&b)){

    streampos size;

    ifstream f(IN_FILE, ios::in);

    f.seekg(0,ios::end);
    size=f.tellg();

    b=new char[size];

    f.seekg(0, ios::beg);
    f.read(b, size);

    f.close();
}
#endif

这是读取的文件:

2 2
1 0
0 1
2 2
i 0
0 -i
2 2
0 1
-1 0
2 2
0 i
i 0

早些时候,我放了一些 cout,看起来 size=60,而实际大小是 49(已检查),文件中换行符的数量是 11,所以恰好是 60-49 .有人可以帮我吗?

Windows 将换行符存储为两个字符:'\r\n',称为回车符 return 和换行符。这就是为什么它被计算了两次:实际上有两个字符要被计算。

Windows 使用“\r\n” 到 return 到行首 (​​'\r') 并开始一个新行 ('\n')。

要从计数中删除它们,您必须读取整个文件并计算 '\r's 的数量。

要添加到其他答案中,如果您想阅读换行符等特殊字符,您应该以 binary 模式而不是文本模式打开文件。

ifstream f(IN_FILE, ios::in | ios::binary);

如果您不以二进制模式打开文件,组成 '\n' 的实际字符将由运行时转换为单个字符(即 '\n')。因此,在文本模式下,根据文件所包含的所有实际字符,您不会获得文件的 "real" 版本。

此外,对于以文本模式打开的文件,seekg()tellg() 等函数将无法按预期工作,或者至少会给您 "wrong results"(实际上函数本身并没有错,但是如果你正在编写一个试图 "hone in" 在文件中的位置上的程序,那就错了)。同样,运行时在幕后完成的换行符(和 EOF)转换会妨碍这些函数按您预期的方式工作。

另一方面,以二进制模式打开的文件允许这些函数按预期工作——没有换行符或 EOF 的转换——无论构成文件内容的各个字节是什么,这就是你得到.

接下来需要确定的是它是 Unix 文本文件还是 Windows 文本文件。根据它是哪一个,行尾将不同。

我假设您在 Windows 上 运行。如果不是,请无视我下面的回答。

Windows 将文本文件中的换行符存储为两个字符(CR LF 或 '\r' '\n')。因此,寻找文件末尾并调用 tellg() 将 return 文件的二进制大小 (60),而不是文本大小 (49)。

为了获得正确的文本大小 (49),一种解决方案是计算每个换行符 (11),然后从总字节大小中减去该数字。