[英]Reading and writing to binary file in C++
我需要制作一個包含“名稱”的文件,該文件是一個字符串-char數組-和“數據”這是字節數組-在C ++中是char數組-但是我遇到的第一個問題是如何分隔“名稱”從“數據”? 在這種情況下,可以使用換行符(假設名稱中沒有“ \\ n”),但是在“數據”部分中可以包含特殊字符,因此無法知道何時結束,因此我將文件中的int值,該數據在具有“數據”大小的數據之前! 我嘗試使用以下代碼來做到這一點:
if((fp = fopen("file.bin","wb")) == NULL)
{
return false;
}
char buffer[] = "first data\n";
fwrite( buffer ,1,sizeof(buffer),fp );
int number[1];
number[0]=10;
fwrite( number ,1,1, fp );
char data[] = "1234567890";
fwrite( data , 1, number[0], fp );
fclose(fp);
但我不知道“ int”部分是否正確,因此我嘗試了許多其他代碼,包括此代碼:
char buffer[] = "first data\n";
fwrite( buffer ,1,sizeof(buffer),fp );
int size=10;
fwrite( &size ,sizeof size,1, fp );
char data[] = "1234567890";
fwrite( data , 1, number[0], fp );
當我打開文件時,我看到的是4個“ NULL”字符,而不是整數。 那是正常的嗎? 我面臨的另一個問題是從文件中再次讀取該信息! 我嘗試讀取的代碼根本不起作用:(我用“ fread”嘗試過,但是我不確定是否應該在其中使用“ fseek”或僅讀取其后的另一個字符。
我想到使用以下類,然后編寫並讀回它:
class Sign
{
public:
char* name;
int size;
char* data;
};
但這在C ++中並非易事!
我還嘗試了以下方法:
void saveData(char* filename) {
fstream filestr;
int n;
n=10;
char* data= "1234567890";
filestr.open (filename, fstream::out | fstream::binary);
for (int j = 0; j<5 ; j++)
{
filestr << n;
for (int i = 0; i < n; i++) {
filestr << data[i];
}
}
filestr.close();
}
void readData(char* filename) {
fstream filestr;
int n =0;
filestr.open (filename, fstream::in | fstream::binary);
int m =0;
//while(!filestr.eof())
while(m<5)
{
filestr >> n;
char *data = new char[n];
for (int i = 0; i < n; i++) {
filestr >> data[i];
}
printf("data is %s\n",data);
m++;
}
filestr.close();
}
但是閱讀也不起作用。
在閱讀時,我得到了奇怪的人物。
到目前為止,對我有用的代碼是這樣的:
void saveData(char* filename) {
fstream filestr;
char * name = "first data\n";
int n;
n=10;
char* data= "asdfghjkl;";
filestr.open (filename, fstream::out | fstream::binary);
for (int j = 0; j<5 ; j++)
{
filestr << name;
filestr << strlen(data);
filestr << data;
}
filestr.close();
}
void readData(char* filename) {
fstream filestr;
int n =0;
filestr.open (filename, fstream::in | fstream::binary);
while(!filestr.eof())
{
string name;
getline(filestr,name,'\n');
printf("name is %s\n",name.c_str());
filestr >> n;
char *data = new char[n];
for (int i = 0; i < n; i++) {
filestr >> data[i];
}
printf("n is%d\ndata is %s\n",n,data);
}
filestr.close();
}
但是閱讀中的問題是:
1-(我認為這不是真正的問題),除了實際數據外,它還打印其他字符。 2-關於readData
函數,我得到了6次輸出(最后一次獲得每個字段為空字段),而我只寫了5次! 有人知道為什么嗎? 與while(!filestr.eof())
嗎?
感謝幫助
首先,您以二進制格式進行的寫入/讀取應該像這樣工作(在此讀取序列之后, read_num
將包含10
)。
FILE* fp = fopen("file.bin", "wb");
int num = 10;
fwrite(&num, sizeof(int), 1, fp);
fclose(fp);
FILE* fp2 = fopen("file.bin", "rb");
int read_num;
fread(&read_num, sizeof(int), 1, fp2);
fclose(fp2);
另外要提一下,這種書寫方式不是C ++方式,而是C方式。 C ++文件操作方式表示流,請參見以下示例:
#include <fstream>
#include <string>
struct data_structure {
std::string name;
std::string description;
int number;
void save(const std::string& filename) {
std::ofstream file(filename.c_str());
file << name.c_str() << std::endl
<< description.c_str() << std::endl
<< number;
}
void load(const std::string& filename) {
std::ifstream file(filename.c_str());
getline(file, name);
getline(file, description);
file >> number;
}
};
int main() {
data_structure d, loaded_d;
d.name = "Name";
d.description = "Description";
d.number = 5;
d.save("file.out");
loaded_d.load("file.out");
return 0;
}
好吧,您的代碼存在一些問題:
fwrite( buffer ,1,sizeof(buffer),fp );
該函數的定義如下:
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
因此,您正在緩沖區中發送信息,說它的大小為1,並且計數為sizeof(buffer)。 這可能對某些事情有用,但通常只是倒退。 嘗試使用:
fwrite(buffer, sizeof(char), strlen(buffer), fp);
這既與字符寬度無關,也沒有常量值,您無需擔心(它幾乎適用於任何字符串)。
另外一件小事:
int number[1];
您只有一個整數,因此只需要使用:
int number;
如果更改后在fwrite
遇到錯誤,請使用以下調用:
fwrite( &number, sizeof(int), 1, fp);
這會將一個整數值寫入文件。
解決此問題后,請查看您的代碼是否有效。 通過更正這些呼叫,當然可以更輕松地進行故障排除。 :)
另外,如果您打算使用字段長度(以int形式寫入文件),則需要設置某種系統來讀取長度,然后讀取數據,並且每個長度都應該有一個長度領域。 使用類絕對是處理該問題的最簡單方法。
編輯:您可能想使用結構和函數而不是類,或者可以將類與方法一起使用。 並不重要,兩者都很簡單。 結構/ FUNC:
struct Record
{
std::string name, data;
};
void writeRecord(Record thisRecord, std::string filename, size_t offset)
{
if ( ( fp = fopen(filename.c_str(), "wb") ) == NULL ) { return NULL; }
fwrite( thisRecord.size(), sizeof(unsigned int), 1, fp); // assuming size() return uint
fwrite( thisRecord.name.c_str(), sizeof(char), name.size(), fp);
// repeat for data or other fields
fclose(fp);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.