有新线的种类吗?

Tit*_*ito 2 c++ getline

为什么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 新行就像记事本 ++ 的新行。那么,是否有任何功能或制作可以读取这些新行的通用功能?

Ada*_*dam 8

有 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,您将在一行中获得所有内容。

大多数优秀的文本编辑器都会在某处设置保存时要使用的行结尾。还有一些命令行实用程序,例如dos2unixunix2dos将文本文件从一个文件转换为另一个文件。


历史记录:

当终端只是一台电子打字机时,ASCII 和文本终端出现了。回车 (CR) 字符\r意味着将打印机的回车放回同一行的开头。\n换行(LF) 字符表示将纸张向上移动一行。Windows 的理念是要开始一个新行,您必须同时执行以下两项操作:CR LF。


Die*_*ühl 6

首先,只有一种换行符:'\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'正在使用。