如何检查文件的最后一行 new_line 字符? C++
How to check last line of file for new_line character? C++
如何检查文件的最后一行是否包含“\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 循环之前检查我的最后一行,这样我就可以 sip 它了,如果文件无效!
- 我的图像显示 CR LF,这是我的问题。对不起的错误。应该只有LF。
有三种不同的方法来表示换行。
- 两个字符 CR LF (\r\n): DOS, OS/2, Microsoft Windows, Symbian, DEC RT-1 1
- 一个字符 CR (\r):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 and hth. - Alf 评论)。文本模式将替换每个新的行标记 CR LF,以及 CR 到 LF。在您的示例中,您有 CR LF 标签。
在二进制模式下,您必须转到一个或两个字符减去文件长度,然后读取()两个字符,然后检查它们是否等于 CR LF。请参见瑞希示例。
您可以使用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之前的一个位置并读取最后一个字符。如果它是一个新行,你就完成了。
您可以使用
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 ] != '[=11=]' ) {
str[ len-1 ] = '[=11=]'; // 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;
}
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";
}
如何检查文件的最后一行是否包含“\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 循环之前检查我的最后一行,这样我就可以 sip 它了,如果文件无效!
- 我的图像显示 CR LF,这是我的问题。对不起的错误。应该只有LF。
有三种不同的方法来表示换行。
- 两个字符 CR LF (\r\n): DOS, OS/2, Microsoft Windows, Symbian, DEC RT-1 1
- 一个字符 CR (\r):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 and hth. - Alf 评论)。文本模式将替换每个新的行标记 CR LF,以及 CR 到 LF。在您的示例中,您有 CR LF 标签。
在二进制模式下,您必须转到一个或两个字符减去文件长度,然后读取()两个字符,然后检查它们是否等于 CR LF。请参见瑞希示例。
您可以使用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之前的一个位置并读取最后一个字符。如果它是一个新行,你就完成了。
您可以使用
fgets(string_name, buffer_size, stdin)
fgets() 包含 new_line 字符,与 gets() 和
不同
与 puts()
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 ] != '[=11=]' ) {
str[ len-1 ] = '[=11=]'; // 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;
}
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";
}