我使用了一个文件,它有 15 行,每行 2 个字符,因此假设文件的大小约为 44 字节,但使用 tellg 函数,大小显示为 58。此外,我积累了代码标识换行符的所有位置的数组,它们都是连续的,因此证实了这个疑问。谢谢!
//Tailfile - This program accepts a file and prints the last 10 lines.
//This function determines the number of lines and how to display it
int lineidentifier(fstream&tailfile,long& position)
{
tailfile.seekg(0,ios::end);//sets the read position at the end of file.
long n=0;//counter for the number of lines
long i=tailfile.tellg();//counter for the number of characters set to
//thenumber of bytes in the file and hence, the end.
char ch;//To hold and check the character.
while(n<10&&i>=0)//conditions are as long as the number of characters
//are not exhausted or the number of lines
{
tailfile.seekg(i, ios::beg);//sets the read position to the end of
//the file by using the number of characters and the file
//mode as the beginning.
cout<<"1. "<<i<<endl;//DEBUGGING EXTRA
tailfile.get(ch);//Reads the content at i
tailfile.clear();//clears the eof flag set by the first iteration
//because we reach the end of the file.
cout<<"2. "<<i<<endl;//DEBUGGING EXTRA
if(ch=='n')//if the character received is the newline character
//leading to us regarding it as a line has been identified.
{
n++;//Increment n accordingly.
position=i;//The position is the byte i is at before the
//character was read, hence the position of the character.
cout<<position<<endl;//DEBUGGING EXTRA
cout<<ch<<endl;//DEBUGGING EXTRA
i--;
}
i--;
cout<<"4. "<<i<<endl;//DEBUGGING EXTRA
}
cout<<i<<endl;//DEBUGGING EXTRA
if(i<=1)//Using the position of i to indicate whether the file has more
//than 10 lines. If i is less than 1, it has reached the
//beginning of the file
return 0;
else
return 1;
}
Linux 使用 n
(换行,0x0A(作为其换行符。
Windows/DOS 使用rn
(回车 (0x0D( 和换行符 (0x0A((作为其换行符。
您可能正在读取 DOS 编码的文件。
此答案提供了更多详细信息。
使用二进制文件编辑器(如 Hexedit(打开文件,您很可能会看到新行使用 nr
编码(0x0A
, "换行" 和 0x0D
, "回车"(,而不仅仅是n
。
顺便说一下,只需使用 getline
读取文件:
std::ifstream infile("thefile.txt");
std::string line;
while (std::getline(infile, line))
{
}
然后,你不用担心EOL是如何编码的......
到目前为止,我看到的答案基本上是正确的,但它们混淆了两个不同的概念。 'n'
和'r'
是转义序列;每个字符都表示一个字符,其值取决于实现。通常,这些值是0x0A和0x0D的,因为这通常很方便,但它们不需要具有这些值。
将字符'n'
写入输出流时,运行时库会执行生成新行所需的任何操作。对于Unix,约定是字节0x0A表示"开始新行"。对于 Windows,约定是字节0x0A表示"向下移动到下一行"(即换行(,字节0x0D表示"移动到当前行的开头";组合将开始一条新行。
在 ASCII 编码中,值 0x0A 和 0x0D 分别表示换行符和回车符。它们与 C/C++ 转义序列没有固有的联系 'n'
和 'r'
。