C++ 交叉编译不处理换行输入文本文件
C++ cross-compile not handling newline input text file
为清楚起见:
这不是 Getting std :: ifstream to handle LF, CR, and CRLF?
的副本
这是
的扩展
我预先说明这一点是因为当我 post 在 编辑问题时,它被标记为可能与 Getting std :: ifstream to handle LF, CR, and CRLF? 重复。我在另一个 post 尝试了提议的解决方案的简化版本(直接读取而不是缓冲区以保持简单)它对我不起作用,即使我编辑了我的问题和代码来证明这一点,也有一直没有回应。乔纳森建议我重新 post 作为一个单独的问题,所以我在这里。
我也尝试过许多其他解决方案,最终得到以下代码,但尽管代码按预期处理了制表符和普通文本,但它仍然没有按预期处理换行符差异,所以我需要帮助。
我想:
- 读入 txt 文件的内容
- 运行 对内容进行一些验证检查
- 将报告输出到另一个 txt 文件
在这个原型代码中,我只是从一个文件中读取文本并将编辑后的文本输出到另一个文件。在我开始工作之后,我会担心 运行 宁验证测试,...
我正在 Linux Mint Maya(基于 Ubuntu 12.04)盒子上编译和测试,然后在 Windows PC 上使用 mingw32 交叉编译到 运行 .
一切正常,当我:
- 使用 linux 创建的文本文件 linux 在 linux 框上编译和 运行
- 使用 linux 创建的文本文件 linux 在 linux 和 运行 上交叉编译 Windows
然而,当我:
- 使用 Windows 创建的文本文件
在 linux 和 Windows 上交叉编译 运行
结果与预期不符;跳过前几个字符。
我需要程序来处理 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 PC 上使用 Windows 创建的文本文件和 运行 程序时,输出是:
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 行没有:
- 第 1 行开头缺少 0 个字符
- 第 2 行开头缺少 3 个字符
- 第 3 行开头缺少 2 个字符
- 第 4 行开头缺少 1 个字符
- 第 5 行开头缺少 0 个字符
我认为这与 linux 和 Windows 文本文件中处理换行符的差异有关,但我已经阅读了其他 postings 并尝试了解决方案,但它似乎并没有解决问题。我确定我遗漏了一些非常基本的东西,如果是的话,请提前道歉,但我已经为此努力了一个多星期,需要帮助。
我使用的代码是:
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;
}
}
}
感谢任何和所有建议...
如果您想 fiddle 手动换行,您必须以二进制模式打开文件。
好吧,感谢 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
并安装它。
我必须包含新安装的路径,并且我必须在编译命令中添加两个选项
- -static-libgcc
- -static-libstdc++
防止出现 2 "missing dll" 条错误消息。
在那之后,交叉编译工作干净利落,换行差异处理也没有问题。
我喜欢技术:花了一个多星期的时间认为我做错了什么,交叉编译器已经过时了。哦,好吧,在此期间我学到了很多关于 C++ 的知识,希望这对将来的其他人有所帮助。
再次感谢
R
为清楚起见:
这不是 Getting std :: ifstream to handle LF, CR, and CRLF?
的副本这是
我预先说明这一点是因为当我 post 在
我也尝试过许多其他解决方案,最终得到以下代码,但尽管代码按预期处理了制表符和普通文本,但它仍然没有按预期处理换行符差异,所以我需要帮助。
我想:
- 读入 txt 文件的内容
- 运行 对内容进行一些验证检查
- 将报告输出到另一个 txt 文件
在这个原型代码中,我只是从一个文件中读取文本并将编辑后的文本输出到另一个文件。在我开始工作之后,我会担心 运行 宁验证测试,...
我正在 Linux Mint Maya(基于 Ubuntu 12.04)盒子上编译和测试,然后在 Windows PC 上使用 mingw32 交叉编译到 运行 .
一切正常,当我:
- 使用 linux 创建的文本文件 linux 在 linux 框上编译和 运行
- 使用 linux 创建的文本文件 linux 在 linux 和 运行 上交叉编译 Windows
然而,当我:
- 使用 Windows 创建的文本文件 在 linux 和 Windows 上交叉编译 运行
结果与预期不符;跳过前几个字符。
我需要程序来处理 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 PC 上使用 Windows 创建的文本文件和 运行 程序时,输出是:
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 行没有:
- 第 1 行开头缺少 0 个字符
- 第 2 行开头缺少 3 个字符
- 第 3 行开头缺少 2 个字符
- 第 4 行开头缺少 1 个字符
- 第 5 行开头缺少 0 个字符
我认为这与 linux 和 Windows 文本文件中处理换行符的差异有关,但我已经阅读了其他 postings 并尝试了解决方案,但它似乎并没有解决问题。我确定我遗漏了一些非常基本的东西,如果是的话,请提前道歉,但我已经为此努力了一个多星期,需要帮助。
我使用的代码是:
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;
}
}
}
感谢任何和所有建议...
如果您想 fiddle 手动换行,您必须以二进制模式打开文件。
好吧,感谢 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
并安装它。
我必须包含新安装的路径,并且我必须在编译命令中添加两个选项
- -static-libgcc
- -static-libstdc++
防止出现 2 "missing dll" 条错误消息。
在那之后,交叉编译工作干净利落,换行差异处理也没有问题。
我喜欢技术:花了一个多星期的时间认为我做错了什么,交叉编译器已经过时了。哦,好吧,在此期间我学到了很多关于 C++ 的知识,希望这对将来的其他人有所帮助。
再次感谢
R