1

私は一般的なテキストファイルリーダークラスを書くのに忙しく、Mac、Linux、およびWindowsの行末(EOL)文字を正しく処理するためのコードを書くのに苦労しています。

この問題について少し読んだことがあります。getline()を使用してテキストファイルの内容を読み取り、文字列をマップに格納すると、TextFileReaderクラス内でEOL文字を削除する次の関数を思いつきました。

//! Strip End-Of-Line characters.
void TextFileReader::stripEndOfLineCharacters( )
{
    // Search through container of data and remove newline characters.
    string::size_type stringPosition_ = 0;
    string searchString_ = "\r";
    string replaceString_ = "";

    for ( unsigned int i = 0; i < 1; i++ )
    {
        for ( iteratorContainerOfDataFromFile_
              = containerOfDataFromFile_.begin( );
              iteratorContainerOfDataFromFile_
              != containerOfDataFromFile_.end( );
              iteratorContainerOfDataFromFile_++ )
            {
                while ( ( stringPosition_ = iteratorContainerOfDataFromFile_
                          ->second.find( searchString_,
                                         stringPosition_ ) ) != string::npos )
                {
                    // Replace search string with replace string.
                    iteratorContainerOfDataFromFile_->second
                        .replace( stringPosition_, searchString_.size( ),
                                  replaceString_ );

                    // Advance string position.
                    stringPosition_++;
                }
            }

        // Switch search string.
        searchString_ = "\n";
    }
}

これにより、クロスプラットフォームのすべてのEOL文字が削除されると思いましたが、そうではないようです。Mac OS 10.5.8を実行している私のMacでは、正常に動作します。ただし、Windowsシステムでは機能しないようです。不思議なことに、この関数を実行しているWindowsシステムでは、マップの最初の文字列のEOL文字が削除され、残りの文字列はまだ1文字長すぎます。

これにより、「\r」と「\n」の文字を置き換えることはできないかもしれないと思いますが、私が読んだすべてのことは、WindowsがEOL文字を表すために使用する2つの組み合わせであることを示唆しています。

より明確にするために、これが私がやろうとしていることの段階的なレイアウトです。testFileMadeWithWindows.txtとtestFileMadeWithMac.txtという2つのテキストファイルがあります。

Windowsマシンでメモ帳を使用して最初のファイルを開くと、次のファイルが含まれています。

これは1行目です。

これは2行目です。

これは3行目です。

Macでテキストエディットを使用して2番目のファイルを開くと、次のファイルが含まれています。

これは1行目です。

これは2行目です。

これは3行目です。

つまり、両方のファイルのファイルの内容は同一であることが意図されています。FileReaderクラスを使用してこれらのファイルを両方とも読み取り、文字列をマップに保存したいと思います。これを実現するために、getline()関数を使用します。

getline()を使用してtestFileMadeWithWindows.txtを読み取ると、文字列のサイズは次のようになります。

16

16

15

同様に、getline()を使用してtestFileMadeWithMac.txtを読み取ると、文字列のサイズは次のようになります。

16

16

15

このデータを含むマップで最初の投稿で投稿したstripEndOfLineCharacters()関数を実行します。

testFileMadeWithWindows.txtの場合、これにより次の文字列サイズになります。

15

16

15

testFileMadeWithMac.txtの場合、これにより次の文字列サイズになります。

15

15

15

string :: compareを使用して、テキストファイルから読み込んだ文字列を予想される文字列データと比較します。これは次のようになります。

これは1行目です。

これは2行目です。

これは3行目です。

Windowsの比較は失敗します。具体的には、2行目との比較は失敗します。Macの比較は、3つの文字列すべてで成功します。Windowsの比較も成功するようにこれを解決する方法を知りたいです。

任意の入力をいただければ幸いです。前もって感謝します!

Kartik

4

1 に答える 1

0

これを行う最善の方法は、常に fstream をテキスト モードで (つまり、fstream::binary を使用せずに) 開くことです。そうすることで、EOL (現在のプラットフォーム上にあるものに関係なく) は単一の '\n' 文字に変換されます。あなた、そしてあなたが心配しなければならないのはそれだけです...

于 2011-05-11T01:18:46.407 に答える