2009-10-12 2 views
2

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

Предназначен для загрузки файла из 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).

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

ответ

15

Я предполагаю, что следующий символ является байтом (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]; 
} 

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

+0

Как я могу это исправить? У меня нет большого опыта в строках стиля С –

+0

Не использовать c_str() - манипулировать с помощью std :: string – Mark

+0

Я использую библиотеку, которая требует ввода строки c. –

2

Один из байтов, вероятно 0. Это означает, что конец строки в COUT при прохождении обугленного * (который c_str есть)

2

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

+0

ОЧЕНЬ хорошая точка о настройке двоичного режима на входе. – catfood

+0

Насколько я могу судить, в PhysFS нет возможности открыть файл в двоичном режиме. Отсутствие надлежащих примеров использования PhysFS - это то, почему я думал, что проблема с чтением файла в памяти вместо проблем с дисплеем. :-( –

+0

Да, я тоже это сказал: не читайте весь файл в памяти. Если, я думаю, вы совершенно уверены, что он будет очень маленьким. – catfood