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 作为一个单独的问题,所以我在这里。

我也尝试过许多其他解决方案,最终得到以下代码,但尽管代码按预期处理了制表符和普通文本,但它仍然没有按预期处理换行符差异,所以我需要帮助。

我想:

在这个原型代码中,我只是从一个文件中读取文本并将编辑后的文本输出到另一个文件。在我开始工作之后,我会担心 运行 宁验证测试,...

我正在 Linux Mint Maya(基于 Ubuntu 12.04)盒子上编译和测试,然后在 Windows PC 上使用 mingw32 交叉编译到 运行 .

一切正常,当我:

然而,当我:

结果与预期不符;跳过前几个字符。

我需要程序来处理 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 行没有:

我认为这与 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