Правильно, пожалуйста, несите меня, поскольку у меня есть две отдельные попытки, которые я расскажу ниже.C++ iostream двоичные проблемы с чтением и записью
Сначала я начал читать руководство (http://www.cplusplus.com/doc/tutorial/files/). Однако, хотя он содержит то, что кажется хорошим примером использования read(), в нем нет примера использования функции write().
Сначала я попытался сохранить простой массив символов в двоичном формате, используя write(). Моя оригинальная идея (и надежда) заключалась в том, что я мог бы добавить в этот файл новые записи, используя ios :: app. Первоначально это работало, но я тоже получал нежелательные результаты. Сообщение на другом форуме для справки предложило, что мне не хватало нулевого терминатора в конце моего массива char. Я применил это (или, по крайней мере, попытался на основе того, как я был показан), как видно из приведенного ниже примера. К сожалению, это означало, что read() больше не функционирует должным образом, потому что он не будет считывать нулевой терминатор.
Мне также сказали, что выполнение char *memoryBlock
является «злоупотреблением» стандартом C++ или чем-то, и является небезопасным, и что я должен определить массив точного размера, то есть char memoryBlock[5]
, однако что делать, если я хочу написать данные char к файлу, который может быть любого размера? Как мне продолжить? В приведенном ниже коде содержатся различные пронумерованные строки кода, указывающие различные попытки, которые я сделал, и различные варианты, в том числе некоторые из предложений, упомянутых выше. Я хочу попробовать использовать код хорошей практики, поэтому, если char *memoryBlock
небезопасно или какие-либо другие строки кода, я хочу исправить это.
Я также хотел бы пояснить, что я пытаюсь писать символы здесь только для целей тестирования, поэтому, пожалуйста, не предлагайте вместо этого писать вместо текстового режима вместо текстового режима. Далее я расскажу о второй части этого вопроса в соответствии с приведенным ниже кодом.
Первый код:
#include <cstdlib>
#include <iostream>
#include <fstream>
//#include <string>
int main()
{
//char memoryBlock[5];
char *memoryBlock;
char *memoryBlockTwo;
std::ifstream::pos_type size;// The number of characters to be read or written from/to the memory block.
std::ofstream myFile;
myFile.open("Example", std::ios::out | /*std::ios::app |*/ std::ios::binary);
if(myFile.is_open() && myFile.good())
{
//myFile.seekp(0,std::ios::end);
std::cout<<"File opening successfully completed."<<std::endl;
memoryBlock = "THEN";
//myFile.write(memoryBlock, (sizeof(char)*4));
//memoryBlock = "NOW THIS";
//strcpy_s(memoryBlock, (sizeof(char)*5),"THIS");
//memoryBlock = "THEN";
//strcpy(memoryBlock, "THIS");
//memoryBlock[5] = NULL;
myFile.write(memoryBlock, (sizeof(char)*5));
}
else
{
std::cout<<"File opening NOT successfully completed."<<std::endl;
}
myFile.close();
std::ifstream myFileInput;
myFileInput.open("Example", std::ios::in | std::ios::binary | std::ios::ate);
if(myFileInput.is_open() && myFileInput.good())
{
std::cout<<"File opening successfully completed. Again."<<std::endl;
std::cout<<"READ:"<<std::endl;
size = myFileInput.tellg();
memoryBlockTwo = new char[size];
myFileInput.seekg(0, std::ios::beg);// Get a pointer to the beginning of the file.
myFileInput.read(memoryBlockTwo, size);
std::cout<<memoryBlockTwo<<std::endl;
delete[] memoryBlockTwo;
std::cout<<std::endl<<"END."<<std::endl;
}
else
{
std::cout<<"Something has gone disasterously wrong."<<std::endl;
}
myFileInput.close();
return 0;
}
Следующая попытка горных работ на том основании, что попытка использовать ИОС :: приложение с прошивкой :: двоичном просто не будет работать, и что ammend файл я должен прочитайте все это, внесите мои изменения, затем напишите назад и замените все содержимое файла, хотя это выглядит несколько неэффективным.
Однако я не читаю и не помещаю содержимое в свой код ниже. То, что я на самом деле пытаюсь сделать, это написать объект пользовательского класса в файл, а затем снова прочитать его обратно.
Это похоже на работу (хотя, если я делаю что-то плохое мудрёный код здесь, пожалуйста, укажите это), ОДНАКО, я, казалось бы, не в состоянии хранить переменный типа std::string
и std::vector
, потому что я получаю нарушение прав доступа, когда я достигаю myFileInput.close(). Поскольку эти переменные-члены закомментированы, нарушение прав доступа не происходит. Мое лучшее предположение о том, почему это происходит, заключается в том, что они используют указатели на другие части памяти для хранения своих файлов, и я сам не записываю данные в свой файл, а указатели на него, которые по-прежнему остаются действительными, когда я читаю мои данные.
Возможно ли вообще сохранить содержимое этих более сложных типов данных в файле? Или я должен разбить все на более основные переменные, такие как символы, ints и floats?
Второй код:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
class testClass
{
public:
testClass()
{
testInt = 5;
testChar = 't';
//testString = "Test string.";
//testVector.push_back(3.142f);
//testVector.push_back(0.001f);
}
testClass(int intInput, char charInput, std::string stringInput, float floatInput01, float floatInput02)
{
testInt = intInput;
testChar = charInput;
testArray[0] = 't';
testArray[1] = 'e';
testArray[2] = 's';
testArray[3] = 't';
testArray[4] = '\0';
//testString = stringInput;
//testVector = vectorInput;
//testVector.push_back(floatInput01);
//testVector.push_back(floatInput02);
}
~testClass()
{}
private:
int testInt;
char testChar;
char testArray[5];
//std::string testString;
//std::vector<float> testVector;
};
int main()
{
testClass testObject(3, 'x', "Hello there!", 9.14f, 6.662f);
testClass testReceivedObject;
//char memoryBlock[5];
//char *memoryBlock;
//char *memoryBlockTwo;
std::ifstream::pos_type size;// The number of characters to be read or written from/to the memory block.
std::ofstream myFile;
myFile.open("Example", std::ios::out | /*std::ios::app |*/ std::ios::binary);
if(myFile.is_open() && myFile.good())
{
//myFile.seekp(0,std::ios::end);
std::cout<<"File opening successfully completed."<<std::endl;
//memoryBlock = "THEN";
//myFile.write(memoryBlock, (sizeof(char)*4));
//memoryBlock = "NOW THIS";
//strcpy_s(memoryBlock, (sizeof(char)*5),"THIS");
//memoryBlock = "THEN AND NOW";
//strcpy(memoryBlock, "THIS");
//memoryBlock[5] = NULL;
myFile.write(reinterpret_cast<char*>(&testObject), (sizeof(testClass)));//(sizeof(char)*5));
}
else
{
std::cout<<"File opening NOT successfully completed."<<std::endl;
}
myFile.close();
std::ifstream myFileInput;
myFileInput.open("Example", std::ios::in | std::ios::binary | std::ios::ate);
if(myFileInput.is_open() && myFileInput.good())
{
std::cout<<"File opening successfully completed. Again."<<std::endl;
std::cout<<"READ:"<<std::endl;
size = myFileInput.tellg();
//memoryBlockTwo = new char[size];
myFileInput.seekg(0, std::ios::beg);// Get a pointer to the beginning of the file.
myFileInput.read(reinterpret_cast<char *>(&testReceivedObject), size);
//std::cout<<memoryBlockTwo<<std::endl;
//delete[] memoryBlockTwo;
std::cout<<std::endl<<"END."<<std::endl;
}
else
{
std::cout<<"Something has gone disasterously wrong."<<std::endl;
}
myFileInput.close();
return 0;
}
Извиняюсь за долгий-windedness этого вопроса, но я надеюсь, что моя тщательность в предоставлении такой информации, как я могу о моих вопросах ускорит появление ответов, даже для этого (что может быть даже простой проблемой для исправления, хотя я искал часы, пытаясь найти решения), поскольку время здесь является фактором. Я буду следить за этим вопросом в течение дня, чтобы дать разъяснения с помощью ответа.
бит трудно следовать. Боюсь, я не могу разобраться с проблемой, потому что вы прокомментировали код, попробуйте указать минимальный код, который воспроизводит ошибку. Как стартер, вы похожи на то, что у вас есть проблемы с распределением памяти. И какая ошибка, вы получаете дамп ядра, или вы получаете дерьмо в файле? – ColWhi
Код, который в настоящее время предоставляется, дает проблемы, которые я описал. Исключая второй пример с векторами и строками, но я объяснил проблему, связанную с запросами на ответы. Все, что вам нужно сделать, это раскомментировать код, относящийся к векторам и строкам в классе. – Interminable
В первом примере это не будет скомпилировано, поскольку memoryBlock не определен. если вы раскомментировали одно из определений, у вас проблемы, потому что вы не выделяете сколько-нибудь или достаточно места. – ColWhi