我需要创建一个包含“name”的文件,这是一个字符串-charay的char-和“data”,它是字节数组--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())
??
感谢您的帮助
答案 0 :(得分:3)
首先,您的二进制格式的写作/阅读应该像这样工作(此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;
}
答案 1 :(得分:0)
嗯,您的代码存在一些问题:
fwrite( buffer ,1,sizeof(buffer),fp );
该功能定义如下:
size_t fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
所以你在缓冲区中发送信息,说它的大小为1,sizeof(缓冲区)的数量。这可能适用于某些事情,但通常只是倒退。尝试使用:
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);
}