如何检查new_line字符的最后一行文件? C ++

时间:2016-04-24 08:27:20

标签: c++ file newline eof getline

如何检查文件中的最后一行是否包含' \ n' (或换行)。

以下是两个例子: a file with newline at the end - a file without newline at the end

我目前的代码:

fstream file("filename");
string line;
if (!file.is_open()) throw Exception();
while(getline(file, line))
{
    (checking for lastline)
}

我意识到getline不会包含new_line字符。我可以浏览每个角色,但会出现性能问题。有些文件包含数百万个字符,我不知道如何转到结束行来获取new_line字符。

--- 编辑 ---

  • 也许我忘了提到我的环境只是UNIX。所以我会 只使用end_line字符' \ n'。
  • 其次,我需要让getline检查每一行是否存在错误(但这里没有相关内容)。
  • 我会在while循环之前检查我的最后一行,所以如果文件无效,我可以啜饮它!
  • 我的图片显示CR LF,这是我的坏事。为这个错误而烦恼。应该只有LF。

4 个答案:

答案 0 :(得分:2)

您可以使用seekg跳转到文件中的任意位置。

file.seekg(-1,ios_base::end);    // go to one position before the EOF
char c;
file.get(c);                     // Read current character
if(c=='\n'){
    cout<<"yes"<<endl;           // You have new_line character
}

所以我们跳到EOF前的一个位置并读取最后一个字符。如果它是一个新行,你就完成了。

答案 1 :(得分:1)

有三种不同的方法来表示新行。

  • 两个字符CR LF(\ r \ n):DOS,OS / 2,Microsoft Windows,Symbian,DEC RT-1 1
  • 一个角色CR(\ r \ n):Commodore,Apple II,Mac OS(直到版本9),Microware OS-9
  • 一个字符LF(\ n):Unix,BeOS,AmigaOS,MorphOS,RISC OS,GNU / Linux,Mac OS X,Multics

不要使用getline(),它会吃新行字符。在二进制模式下使用read()(参见Cheers和hth。 - Alf评论)。文本模式将替换每个新行标记CR LF和CR到LF。在您的示例中,您有CR LF标记。

在二进制模式下,您必须转到一个或两个字符减去文件长度,然后读取()两个字符,然后检查它们是否等于CR LF。参见Rishit示例。

答案 2 :(得分:1)

getline的问题在于它会读取行并将它们放入std :: string中,但会删除换行符。您需要的是使用二进制模式读取功能。最困难的任务是让它找到所有可能的新行组合,并使用各种文件大小,最后使它看起来优雅。以下是我尝试如何做到这一点。

问题是,例如,您的平台是否将新行存储为'\ r \ n',那么如果\ n或\ r,还会在最后一行计为新行?

http://coliru.stacked-crooked.com/a/06f70dd4ef5c63c8

    std::ofstream ofs("test.txt");
    ofs << "test \n" << "test 2\n";
    //ofs << "\r";
    ofs.close();

    std::ifstream ifs("test.txt", std::ifstream::binary);

    // Read last two chars, it might also read only one last char
    std::vector<char> end_file_chars;
    for (int pos = 1; pos <= 2; ++pos) {
        if (!ifs.seekg(-pos, std::ios::end)) break;
        char c;
        if (ifs.get(c)) end_file_chars.insert(end_file_chars.begin(), c);
    }

    // Possible end file characters
    std::vector<std::vector<char>> endlines = {{'\r', '\n'},
                                               {'\n'},
                                               {'\r'}};

    // Predicate to compare possible endline with what was found in the file.
    auto checkFn = [&](auto &endline) {
        // Equal compares possible endline in reverse order
        return std::equal(endline.rbegin(), endline.rend(), end_file_chars.rbegin());
    };

    // If any end file character was read and if it acually is end file character...
    if (!end_file_chars.empty() && std::find_if(endlines.begin(), endlines.end(),checkFn) != endlines.end()) {
        std::cout << "Found";
    }
    else {
        std::cout << "Not Found";
    }

答案 3 :(得分:0)

您可以使用

fgets(string_name, buffer_size, stdin)

fgets()包含new_line字符,与gets()和
不同 与puts()

不同,fputs()排除new_line字符

http://www.cplusplus.com/reference/cstdio/fgets/

示例:

while( fgets(str, sizeof(str), stdin) ) {
    // check newline at end of string
    int len = strlen(str);

    if( str[ len-1 ] != '\0' ) {
        str[ len-1 ] = '\0'; // make sure there's no new_line at the end
        len--;
    }

    // now check for empty string, if thus, then last line
    if( strcmp(str, "") == 0 ) break;
}