Я пытаюсь сохранить строки непосредственно в файле для последующего чтения в C ++ (в основном для полного объема я пытаюсь сохранить в файле массив объектов со строковыми переменными, и эти строковые переменные будут прочитаны через нечто вроде объекта [0] .String). Однако каждый раз, когда я пытаюсь прочитать строковые переменные, система выдает мне ошибку. Следующие коды являются основной частью того, что я пытаюсь.
#include <iostream>
#include <fstream>
using namespace std;
/*
//this is run first to create the file and store the string
int main(){
string reed;
reed = "sees";
ofstream ofs("filrsee.txt", ios::out|ios::binary);
ofs.write(reinterpret_cast<char*>(&reed), sizeof(reed));
ofs.close();
}*/
//this is run after that to open the file and read the string
int main(){
string ghhh;
ifstream ifs("filrsee.txt", ios::in|ios::binary);
ifs.read(reinterpret_cast<char*>(&ghhh), sizeof(ghhh));
cout<<ghhh;
ifs.close();
return 0;
}
Вторая часть — то, где дела идут плохо, когда я пытаюсь прочитать это.
Извините, если меня об этом спрашивали раньше, я осмотрел похожие вопросы, но большинство из них немного отличается от того, что я пытаюсь сделать, или я не совсем понимаю, что они пытаются сделать (все еще довольно новичок в этом).
Вы не можете использовать std::istream::read()
читать в std::string
объект. Что вы можете сделать, это определить размер файла, создать строку подходящего размера и прочитать данные в массив символов строки:
std::string str;
std::ifstream file("whatever");
std::string::size_type size = determine_size_of(file);
str.resize(size);
file.read(&str[0], size);
Сложный бит определяет размер строки. Учитывая, что последовательность символов может переводиться во время чтения, например, потому что последовательности конца строки преобразуются, это в значительной степени сводится к чтению строки в общем случае. Таким образом, я бы рекомендовал не делать это таким образом. Вместо этого я бы прочитал строку, используя что-то вроде этого:
std::string str;
std::ifstream file("whatever");
if (std::getline(file, str, '\0')) {
...
}
Это работает нормально для текстовых строк и примерно так же быстро, как и на большинстве систем. Если файл может содержать нулевые символы, например, потому что он содержит двоичные данные, это не совсем работает. Если это так, я бы использовал промежуточный std::ostringstream
:
std::ostringstream out;
std::ifstream file("whatever");
out << file.rdbuf();
std::string str = out.str();
Вы читаете из файла и пытаетесь поместить данные в саму строковую структуру, перезаписывая ее, что совершенно неправильно.
Как это можно проверить на http://www.cplusplus.com/reference/iostream/istream/read/ , типы, которые вы использовали, были неверны, и вы знаете это, потому что вы должны были заставить std::string
в char *
используя reinterpret_cast
,
C ++ Подсказка: используя reinterpret_cast
в С ++ всегда (почти) признак того, что вы сделали что-то не так.
Давным-давно читать файл было легко. В каком-то языке, похожем на Basic, вы использовали функцию LOAD
, а также вуаля!, у тебя был твой файл
Так почему мы не можем сделать это сейчас?
Потому что вы не знаете, что в файле.
Более общим решением является чтение файла (таким образом, в C ++, fstream), байт на байт с использованием функции get (см. http://www.cplusplus.com/reference/iostream/istream/get/), и сделайте себе операцию, чтобы преобразовать его в ожидаемый вами тип, и остановитесь на EOF.
std::isteam
Интерфейс имеет все функции, необходимые для чтения файла различными способами (см. http://www.cplusplus.com/reference/iostream/istream/), и даже в этом случае для std::string
читать файл, пока не найден разделитель (обычно «\ n», но это может быть что угодно, смотрите http://www.cplusplus.com/reference/string/getline/)
std::string
!!!Хорошо, я понимаю.
Мы предполагаем, что в файле содержится содержимое std::string
, но сохраняя его совместимым со строкой в стиле C, то есть \0
символ обозначает конец строки (если нет, нам нужно загрузить файл до достижения EOF).
И мы предполагаем, что вы хотите, чтобы содержимое файла полностью загружалось после выполнения функции loadFile
возвращается.
Итак, вот loadFile
функция:
#include <iostream>
#include <fstream>
#include <string>
bool loadFile(const std::string & p_name, std::string & p_content)
{
// We create the file object, saying I want to read it
std::fstream file(p_name.c_str(), std::fstream::in) ;
// We verify if the file was successfully opened
if(file.is_open())
{
// We use the standard getline function to read the file into
// a std::string, stoping only at "\0"std::getline(file, p_content, '\0') ;
// We return the success of the operation
return ! file.bad() ;
}
// The file was not successfully opened, so returning false
return false ;
}
Если вы используете компилятор с поддержкой C ++ 11, вы можете добавить эту перегруженную функцию, которая будет стоить вам ничего такого (в то время как в C ++ 03, за исключением оптимизаций, это мог обошлись вам во временном объекте):
std::string loadFile(const std::string & p_name)
{
std::string content ;
loadFile(p_name, content) ;
return content ;
}
Теперь для полноты я написал соответствующий saveFile
функция:
bool saveFile(const std::string & p_name, const std::string & p_content)
{
std::fstream file(p_name.c_str(), std::fstream::out) ;
if(file.is_open())
{
file.write(p_content.c_str(), p_content.length()) ;
return ! file.bad() ;
}
return false ;
}
И вот, «основной» я использовал для проверки этих функций:
int main()
{
const std::string name(".//myFile.txt") ;
const std::string content("AAA BBB CCC\nDDD EEE FFF\n\n") ;
{
const bool success = saveFile(name, content) ;
std::cout << "saveFile(\"" << name << "\", \"" << content << "\")\n\n"<< "result is: " << success << "\n" ;
}
{
std::string myContent ;
const bool success = loadFile(name, myContent) ;
std::cout << "loadFile(\"" << name << "\", \"" << content << "\")\n\n"<< "result is: " << success << "\n"<< "content is: [" << myContent << "]\n"<< "content ok is: " << (myContent == content)<< "\n" ;
}
}
Если вы хотите сделать больше, вам нужно будет изучить API библиотеки C ++ IOStreams по адресу http://www.cplusplus.com/reference/iostream/
Строковый объект — это не просто массив символов, а строка
ifs.read(reinterpret_cast<char*>(&ghhh), sizeof(ghhh));
это, вероятно, корень ваших проблем.
попробуйте применить следующие изменения:
char[BUFF_LEN] ghhh;
....
ifs.read(ghhh, BUFF_LEN);