Работа с кросс-платформенными символами конца строки в C ++ - PullRequest
1 голос
/ 11 мая 2011

Я занят написанием универсального класса для чтения текстовых файлов и изо всех сил пытаюсь написать код для правильной работы с символами конца строки (EOL) для Mac, Linux и Windows.

I 'Я немного прочитал эту проблему, и в моем классе TextFileReader появилась следующая функция для удаления символов EOL, когда я прочитал содержимое текстового файла с помощью getline () и сохранил строки в карте.

//! 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 под управлением Mac OS 10.5.8.Похоже, он не работает в системах Windows.Странно, что в системах Windows, в которых эта функция запущена, лишает символ EOL первой строки на карте, а остальные все еще слишком длинны на один символ.

Это заставляет меня думать, что, возможно, я не могу простозамените символы "\ r" и "\ n", но все, что я прочитал, говорит о том, что это комбинация двух символов, которые Windows использует для представления символов EOL.

Чтобы сделать это более явным, вот пошаговыйШаг за шагом, что я пытаюсь сделать.У меня есть два текстовых файла с именем testFileMadeWithWindows.txt и testFileMadeWithMac.txt.

Откройте первый файл с помощью Блокнота на компьютере с Windows, и он содержит следующее.

Это строка 1.

Это строка 2.

Это строка 3.

Откройте второй файл с помощью TextEdit на Mac, и он содержит следующее.

Это строка 1.

Это строка 2.

Это строка 3.

Другими словами, содержимое файла обоих файловпредназначен быть идентичным.Я хочу прочитать оба этих файла, используя мой класс FileReader, и сохранить строки в картах.Для этого я использую функцию getline ().

Когда я читаю в testFileMadeWithWindows.txt с использованием getline (), получается, что размеры строк следующие:

16

16

15

Аналогично, когда я читаю в testFileMadeWithMac.txt с использованием getline (), получается, что размеры строк следующие:

16

16

15

Теперь я выполняю функцию stripEndOfLineCharacters (), которую я опубликовал в своем первом посте на картах, содержащих этуdata.

Для testFileMadeWithWindows.txt это приводит к следующим размерам строк:

15

16

15

Для testFileMadeWithMac.txt это приводит к следующим размерам строк:

15

15

15

Я используюстрока :: сравнить, чтобы сравнить строки, которые я прочитал из текстовых файлов, с ожидаемыми строковыми данными, которые должны быть:

Thisэто строка 1.

Это строка 2.

Это строка 3.

Сбой сравнения Windows, в частности сравнение со второй строкой.Сравнение Mac успешно для всех трех строк.Я хотел бы знать, как решить эту проблему, чтобы сравнение Windows также было успешным.

Любой вклад будет оценен.Заранее спасибо!

Картик

1 Ответ

0 голосов
/ 11 мая 2011

Лучший способ сделать это - всегда открывать ваши потоки в текстовом режиме (т.е. без fstream :: binary), и таким образом EOL (какими бы они ни были на текущей платформе) будут преобразованы в один '\ n «персонажи для вас, и это все, что вам нужно беспокоиться о ...

...