基本上,窗口文本编辑器会放置" \ r" " \ n"在末尾。所以,当我有一个单词"编译"在窗口的文件中,它实际上是"编译\ n \ r",
当我使用
提取字符时char letter;
fin.get(Letter);
从文件中并将我的链表放入char字符
list<char> myList;
我会得到{&#39; c&#39;,&#39; o&#39;,&#39; m&#39;,&#39; p&#39;,&#39; l&#39我的列表中列出了,&#39;我,&#39; e&#39;,&#39; \ r&#39;,&#39; \ n&#39;}。
然后我打电话
itr = myList.end();
它会给包含值的迭代器&#39; \ n&#39;,是吗?因此,如果我想访问&#39; e,我必须做&#34; - itr&#34;两次。是吗??
然后当它是Linux时,我会{&#39; c&#39;,&#39; o&#39;,&#39; m&#39;,&#39; p&#39;,& #39; l&#39;,&#39; i&#39;,&#39; e&#39;,&#39; \ n&#39;},并且调用&#34; itr = myList.end() &#34;会给我一个包含值&#39; \ n&#39;的迭代器,所以我必须做&#34; - 迭代器&#34;到达角色&#39;。我的理解是否正确?
基本上,我使用记事本作为我的文本文件,当我有一个单词&#34;编译&#34;没有空间,当我打电话&#34; itr = myList.end()&#34;它给了我包含一些空间的迭代器,我不知道它是什么。然后,当我做&#34; - itr&#34;它给了我包含最后一个字母的迭代器,而我希望在我做的时候有最后一个字母迭代器&#34; - itr&#34;两次因为它是window的文本文件。
有人可以解释发生了什么吗?
答案 0 :(得分:0)
首先,正如NathanOliver所指出的那样, std::list::end
会在容器的最后一个元素之后返回元素的迭代器。
在您的情况下,对于Windows CRLF行尾,auto it = myList.end(); it--
将包含it
包含LF(0x0A)。在Linux LF行尾的情况下,它也将包含LF。
对于Windows CRLF文件,第二个it--
会指向0x0D,或者在您的示例中指向e
的{{1}}。
因此,您可以在第二个compile
上使用简单条件来检查它是否为0x0D。如果是,您知道该文件是Windows格式,并且需要再次递减迭代器以获取最后一个字符。
为了说明这一点,请查看以下代码。这是非常有限的:没有错误检查,没有边界检查等。
请注意,有更好的方法来处理打开/处理未知行结尾的文件,而不是下面的示例代码
--it
为了测试下面的代码,我做了以下事情:
int main(int argc, char** argv)
{
char buffer;
list<char> l;
ifstream f;
// f.open("crlf.txt");
f.open("lf.txt");
while (f.get(buffer).good())
l.push_back(buffer);
auto it = l.end();
it--;
if (*it == 0x0A) // if true it's LF or CRLF file
{
--it;
if (*it == 0x0D) // if true it's CRLF
{
cout << "File is CRLF / Windows" << endl;
--it; // get to the char before the newline
}
else
cout << "File is LF / Linux" << endl;
}
// 'it' here always refers to the last character
cout << "'it' points to " << *it << endl;
return 0;
}