为清楚起见:
这不是Getting std :: ifstream to handle LF, CR, and CRLF?
的副本这是C++ cutting off character(s) when read lines from file
的扩展我预先说明了这一点,因为当我在C++ cutting off character(s) when read lines from file发布问题时,它被标记为Getting std :: ifstream to handle LF, CR, and CRLF?的潜在副本。我尝试了一个简化版本(直接读取而不是缓冲区以保持简单)所提出的解决方案在另一篇文章中它对我不起作用,即使我编辑了我的问题和代码来证明这一点,也没有回复。乔纳森建议我重新发布一个单独的问题,所以我在这里。
我还尝试了许多其他解决方案,最后得到了下面的代码,但是虽然代码按预期处理了标签和普通文本,但它仍然没有像预期的那样处理新行字符差异所以我需要帮助。
我想:
在这个原型代码中,我只是从一个文件中读取文本并将编辑后的文本输出到另一个文件。在我开始工作后,我会担心运行验证测试,......
我正在Linux Mint Maya(基于Ubuntu 12.04)的盒子上进行编译和测试,然后使用mingw32进行交叉编译,以便在Windows PC上运行。
当我:
时,一切正常然而,当我:
结果不符合预期;跳过前几个字符。
我需要该程序来处理Windows创建或Linux创建的文本文件。
(我现在用作测试的傻内容)输入文件我在所有情况下使用(一个在linux盒子上创建;一个在Windows上使用记事本创建)是:
A new beginning
just in case
the file was corrupted
and the darn program was working fine ...
at least it was on linux
当我读入文件并使用该程序(如下所示的代码)时,linux创建的文本文件会产生正确的输出:
Line 1: A new beginning
Line 2: just in case
Line 3: the file was corrupted
Line 4: and the darn program was working fine ...
Line 5: at least it was on linux
当我使用Windows创建的文本文件并在Windows PC上运行程序时,输出为:
Line 1: A new beginning
Line 2: t in case
Line 3: e file was corrupted
Line 4: nd the darn program was working fine ...
Line 5: at least it was on linux
正如您所看到的,2,3,4行中缺少字符,而不是1,5:
我希望这与linux和Windows文本文件中处理换行符的差异有关,但我已经阅读了其他帖子并尝试了解决方案,但它似乎没有解决问题。我确信我错过了一些非常基本的东西并提前道歉,如果是这样,但我已经在这一段时间内敲打了一个多星期并需要帮助。
我使用的代码是:
int main(int argc, char** argv)
{
/*
*Program to:
* 1) read from a text file
* 2) do some validation checks on the content of that text file
* 3) output a report to another text file
*/
std::string rc_input_file_name = "rc_input_file.txt";
std::string rc_output_file_name = "rc_output_file.txt";
char *RC_INPUT_FILE_NAME = new char[ rc_input_file_name.length() + 1 ];
strcpy( RC_INPUT_FILE_NAME, rc_input_file_name.c_str() );
char *RC_OUTPUT_FILE_NAME = new char[ rc_output_file_name.length() + 1 ];
strcpy( RC_OUTPUT_FILE_NAME, rc_output_file_name.c_str() );
std::ifstream rc_input_file_holder;
rc_input_file_holder.open( RC_INPUT_FILE_NAME , std::ios::in );
if ( ! rc_input_file_holder.is_open() )
{
std::cout << "Error - Could not open the input file" << std::endl;
return EXIT_FAILURE;
}
else
{
std::ofstream rc_output_file_holder;
rc_output_file_holder.open( RC_OUTPUT_FILE_NAME , std::ios::out | std::ios::trunc );
if ( ! rc_output_file_holder.is_open() )
{
std::cout << "Error - Could not open or create the output file" << std::endl;
return EXIT_FAILURE;
}
else
{
std::streampos char_num = 0;
long int line_num = 0;
long int starting_char_pos = 0;
std::string file_line = "";
while ( getline( rc_input_file_holder , file_line ) )
{
line_num = line_num + 1;
long unsigned file_line_length = file_line.length();
std::string string_to_find = "\r";
std::string string_to_insert = "\n";
long unsigned num_char_in_string_to_find = string_to_find.length();
long unsigned character_position;
while ( ( character_position = file_line.find( string_to_find ) ) != std::string::npos )
{
if ( character_position == file_line_length - num_char_in_string_to_find )
{
// If the \r character is found at the end of the line,
// it is the old Mac style newline,
// so replace it with \n
file_line.replace( character_position , num_char_in_string_to_find , string_to_insert );
file_line_length = file_line.length();
}
else
{
// If the \r character is found but is not the last character in the line
// it could be the second-last character meaning it is a Windows newline pair \r\n
// or it could be somewhere in the middle of the line
// so delete it
file_line.erase( character_position , num_char_in_string_to_find );
file_line_length = file_line.length();
}
}
int field_display_width = 4;
rc_output_file_holder << "Line " << line_num << ": " << file_line << std::endl;
starting_char_pos = rc_input_file_holder.tellg();
}
rc_input_file_holder.close();
rc_output_file_holder.close();
delete [] RC_INPUT_FILE_NAME;
RC_INPUT_FILE_NAME = 0;
delete [] RC_OUTPUT_FILE_NAME;
RC_OUTPUT_FILE_NAME = 0;
}
}
}
任何和所有建议都赞赏......
答案 0 :(得分:1)
好的,感谢Martin Schlott在他的编译器上尝试了我的程序,并使用了来自Windows或Linux源的文本文件。
这指出了编译器的差异,这是关键。
apt-get install mingw32安装的交叉编译器为交叉编译安装了较旧的编译器(v4.2.1),但apt-get install g ++将linux编译器放在v 4.6.2。
所以我在sourceforge上为交叉编译器的v4.6.3找到了一个旧的列表
Mingw with G++ v4.6.3
并安装它。
我必须包含新安装的路径,我必须在编译命令中添加两个选项
防止2“丢失dll”错误消息。
之后,交叉编译工作得很干净,新行差异处理没问题。
我喜欢科技:花一个多星期的时间以为我做错了什么,交叉编译器已经过时了。哦,我在此期间学到了很多关于C ++的知识,并希望将来可以帮助其他人。
再次感谢 [R
答案 1 :(得分:-1)
如果您想手动设置换行符,则必须以二进制模式打开文件。