Добрый день, я работаю над программой, которая читается в двоичном файле (функции для чтения указаны и работают), а затем записывают измененную информацию обратно в другой двоичный файл. (Я меняю между двумя форматами.) Если я использую std :: cout, чтобы выдать номера на консоли прямо перед (или после), я использую streamstream для их записи в файл. Я выхожу из числа, которое я ожидаю, но если я знаю, вводят их в поток через << или записывают, а затем просматривают содержимое файла. (Преобразование из этого формата в оригинальное существует, и я могу его использовать.) Затем я получаю мусор.
struct Record {
unsigned latch;
float e, x, y, u, v, wt;}
Я прочитал в данном файле и изменил числа, которые я читал. (Ниже приведена часть основной функции). Заголовок h определен и существует конструктор по умолчанию. phpp.read и копия даны и работают. Reclen соответствует длине записи и гарантирует, что заголовок написан правильно, потому что он может отличаться для разных входов.
std::ofstream outs;
outs.open(outfile, std::ios::out | std::ios::trunc);
Header h;
outs.write((char*) &h, reclen - 5);
for (int i=0; i<nMax; ++i){
phsp.read(mp);
copy(mp, ep);
Record rec;
Измените числа и поместите их в rec, который является структурой и указан выше. Запись должна быть записана в файл
outs<<rec.latch<<rec.e<<rec.x<<rec.y<<rec.u<<rec.v<<rec.wt;
outs.write((char*) &rec.latch, 4);outs.write((char*) &rec.e, 4);
outs.write((char*) &rec.x, 4); outs.write((char*) &rec.y, 4);
outs.write((char*) &rec.u, 4);outs.write((char*) &rec.v, 4);
outs.write((char*) &rec.wt, 4);
outs.write((char*) &rec, reclen);
}
Ни один из них не пишет, что я хочу в файл, но если я выдам номера через std :: cout и консоль. Я получаю ожидаемые цифры.
std::cout<<rec.latch<<' '<<rec.e<<' '<<rec.x<<' '<<rec.y<<' '<<rec.u<<' '<<rec.v<<
' '<<rec.wt<<'\n';
Я также проверил поток аутов с помощью good(), и я также проверил, что файл открыт. Я также могу записать в файл. Кроме того, запись и вывод << не дают того же выхода (можно было ожидать). Я проверил размер rec.i, и он также соответствует размеру структур. В конце я снова меняю заголовок, потому что у меня появилась новая информация.
outs.seekp(5);
outs.write((char*) &h, reclen - 5);
outs.close();
Там у меня тоже такая же проблема, с ложными цифрами. Я заметил, что число 0 соответствует 0, но число 1 преобразуется в 16777216 для неподписанного числа int.
Надеюсь, ты поможешь мне, я понятия не имею, что случилось.
Вам нужно решить, должен ли ваш новый формат файла использовать двоичное или текстовое представление данных.
Обычно, когда вы используете ofstream::write()
вы сохраняете свои данные в двоичном формате, что означает, что он будет представлен как массив байтов с длиной, равной структуре данных, которую вы пишете. Поэтому то, что вы найдете в файле, будет не числом, а его двоичным представлением, которое обычно выглядит как мусор, если рассматривать его как текст.
Вы можете увидеть число с помощью шестнадцатеричного редактора, или вы можете прочитать его, а затем интерпретировать его как тип вашего выбора. Например:
float number;
ifs.read(&number, sizeof(float); // read in the 4 bytes from the file into a float
Это эквивалентно:
char* buffer = new char[sizeof(float)];
ifs.read(buffer, sizeof(float)];
float f = *(reinterpret_cast<float*>(buffer));
Если вы распечатали содержимое буфера перед его литье, вы увидите тот же мусор, который вы видите в своем файле. Обратите внимание, что для чтения и записи двоичных данных требуется набор ios::binary
flag.
operator<<
обычно используется для записи данных в виде текста. Он менее эффективен с точки зрения пространства и скорости, но имеет преимущество быть читаемым человеком. Запись данных в виде текста так же просто, как печать на экране, например
std::ofstream ofs;
ofs.open("file.txt");
float f = 1.337f;
ofs << "My float: " << f;
std::cout << "My float: " << f;
Если вы используете вышеприведенный код в той же области, нет никакого способа, чтобы содержимое вашего файла отличалось от того, что показано на вашем экране.
Наконец, убедитесь, что ваши переменные инициализированы перед их использованием, как в коде, который вы опубликовали, вы этого не делаете. Например
Header h; // <-- this probably contains rubbish until initialized with some values
outs.write((char*) &h, reclen - 5); // <-- writes rubbish