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

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

本文关键字:换行符 两个 Istream txt 文件 c++      更新时间:2023-10-16

我有一个小问题。似乎出于某种原因,我的函数在计算.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

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

为了添加到其他答案中,如果要读取特殊字符(例如换行符),则应以binary模式而不是文本模式打开文件。

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

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

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

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

接下来你需要确定的是它是Unix文本文件还是Windows文本文件。 根据它是什么,行尾会有所不同。

Windows 使用"\r"返回到行首 ('\r') 并开始一个新的行首 ('')。

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

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

我假设你在Windows上运行。如果没有,请忽略我在下面的回答。

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

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