C ++ c_str не возвращает всю строку - PullRequest
2 голосов
/ 12 октября 2009

Я пробовал следующий код как с обычными ifstreams, так и с текущим бустом: iostream, который я использую, оба имеют одинаковый результат.

Он предназначен для загрузки файла из Physfs в память, а затем передачи его обработчику для обработки (например, изображения, аудио или данных). В настоящее время, когда вызывается c_str, он возвращает только небольшую часть файла.

        PhysFS::FileStream file("Resources/test.png" , PhysFS::OM_READ);

    if(file.is_open()) {

        String* theFile;

        theFile = new String((std::istreambuf_iterator<char>(file)), 
        std::istreambuf_iterator<char>());

        String::iterator it;
        for ( it=theFile->begin() ; it < theFile->end(); it++ ) {
            std::cout << *it; 
        } // Outputs the entire file

        std::cout << theFile->c_str(); // Outputs only the first few lines

    }

Цикл итератора выводит весь png-файл, как и ожидалось, но вызов c_str возвращает только первые несколько символов (\ 211PNG).

Я довольно долго пробовал варианты этого кода, но безуспешно. Есть идеи?

Ответы [ 3 ]

15 голосов
/ 12 октября 2009

Я представляю, что следующий символ - это нулевой (ASCII 0) байт. c_str () просто дает вам * char, поэтому ваша запись в stdout интерпретируется как строка класса C, которая заканчивается первым нулевым байтом.

Если вам действительно нужен C-подобный интерфейс для этой строки, главное, чтобы theFile-> c_str () указывал на ваши данные, а theFile.length - количество символов в строке. Так что вы можете сделать что-то вроде этого:

char *c_value = theFile->c_str()
for (int i = 0; i < theFile.length; i++)
{
   cout << c_value[i];
}

Реальное решение зависит от того, почему вы сначала конвертируете в символ *. Если вы вызываете унаследованную функцию, которая принимает только символ *, вероятно, у этой устаревшей функции также есть аргумент длины.

2 голосов
/ 12 октября 2009

Я бы рассмотрел использование std::vector<unsigned char> вместо std::string для этого. Намного легче иметь дело с двоичными данными в векторе. Вы можете ссылаться на базовый указатель, используя &vec[0], если вам нужен доступ к массиву C-style . Я также хотел бы убедиться, что ваша файловая абстракция также использует std::ios_base::binary для режима файлов под капотом.

2 голосов
/ 12 октября 2009

Один из байтов, вероятно, равен 0. Это означает конец строки в cout при передаче символа * (что такое c_str)

...