Чтение строки из файла в Stack Overflow

Я пытаюсь сохранить строки непосредственно в файле для последующего чтения в 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;
}

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

2

Решение

Вы не можете использовать 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();
4

Другие решения

Что я делаю неправильно?

Вы читаете из файла и пытаетесь поместить данные в саму строковую структуру, перезаписывая ее, что совершенно неправильно.

Как это можно проверить на 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/

4

Строковый объект — это не просто массив символов, а строка

ifs.read(reinterpret_cast<char*>(&ghhh), sizeof(ghhh));

это, вероятно, корень ваших проблем.

попробуйте применить следующие изменения:

char[BUFF_LEN] ghhh;
....
ifs.read(ghhh, BUFF_LEN);
0
По вопросам рекламы [email protected]