为什么windows“记事本”无法读取特定的“新行”而“notepad++”可以读取它们?
好吧,这不是问题。我的问题是“std::ifstream::getline”,它会读取所有内容,直到遇到“那些只能由 windows 记事本识别的新行”,例如:“windows 记事本”将如下所示:
12345
67890
Run Code Online (Sandbox Code Playgroud)
notepad++ 如下:
1
2
3
4
...
Run Code Online (Sandbox Code Playgroud)
而 "std::ifstream::getline" 会得到 "12345" ?!!!
我需要通过 std::fstream 解析 csv 文件,csv 新行就像记事本 ++ 的新行。那么,是否有任何功能或制作可以读取这些新行的通用功能?
有 3 种常见的行结束样式,由\n("line-feed", or "newline") 和\r("carriage return") 字符组成:
\r\n : 窗户风格\n : UNIX 风格(包括 Mac OSX)\r :Mac 风格(OSX 之前)几乎每个处理文本的程序都会接受其中的任何一个作为换行符。我说几乎是因为原生 Windows 控件没有。记事本只是一个包裹在窗口框架中的 Win32 文本区域控件。这意味着在 win32 中使用文本时,您必须手动使用 Windows 样式的行尾。不仅是记事本,而且如果您在 Win32 弹出窗口中有一个多行字符串,例如,您必须确保使用\r\nelse,您将在一行中获得所有内容。
大多数优秀的文本编辑器都会在某处设置保存时要使用的行结尾。还有一些命令行实用程序,例如dos2unix或unix2dos将文本文件从一个文件转换为另一个文件。
历史记录:
当终端只是一台电子打字机时,ASCII 和文本终端出现了。回车 (CR) 字符\r意味着将打印机的回车放回同一行的开头。\n换行(LF) 字符表示将纸张向上移动一行。Windows 的理念是要开始一个新行,您必须同时执行以下两项操作:CR LF。
首先,只有一种换行符:'\n'. 然而,在系统上有一个行结束序列,由换行符和回车符 ( "\n\r") 或回车符和换行符 ( "\r\n") 组成(这些对于使用打印头写入字符的打印机来说是有意义的:发送换行符将移动到下一个行,但保持在该位置并发送回车符会将头部移动到行的开头)。从表面上看,您有一个使用换行符和回车符用于不同目的的文件,但以文本模式读取文件会合并行尾序列。std::ios_base::binary部分谜团可能可以通过以二进制模式打开文件来解决,即在打开文件时添加标志。
但是,这不会改变 的行为std::getline():该函数最多读取第一行终止字符,默认情况下为换行符 ( '\n')。要读取不同字符的行,您可以将其作为附加参数传递(我使用非成员函数,因为它处理任意长字符串而不是成员函数读取char数组;成员函数可以类似地使用):
std::ifstream in("file.csv", std::ios_base::binary);
for (std::string line; std::getline(in, line); ) {
std::istringstream sin(line);
for (std::string field; std::getline(sin, field, '\r'); ) {
std::cout << "field='" << field << "'\n";
}
}
Run Code Online (Sandbox Code Playgroud)
根据您的描述,您的文件似乎用作'\r'字段分隔符。它可能是不同的东西,通过以二进制模式打开文件,然后打印各个字符及其各自的代码,最容易找到它:
std::ifstream in("file.csv", std::ios_base::binary);
for (std::istreambuf_iterator<char> it(in), end; it != end; ++it) {
std::cout << std::setw(3)
<< int(static_cast<unsigned char>(*it)) << ' ' << *it << '\n';
}
Run Code Online (Sandbox Code Playgroud)
这只会打印每个字符的代码和字符本身。您应该能够找到字段分隔符的值,但我猜'\r'正在使用。
| 归档时间: |
|
| 查看次数: |
4413 次 |
| 最近记录: |