2

我需要制作一个包含“name”的文件,它是一个字符串-char数组-和“data”,它是字节数组-C++中的char数组-但我面临的第一个问题是如何分隔“name”从“数据”?换行符在这种情况下可以工作(假设我的名称中没有“\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())吗??

感谢帮助

4

2 回答 2

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;
}
于 2010-05-01T16:24:47.637 回答
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);

这会将一个整数的值写入文件。

在你修复它之后,看看你的代码是否有效。纠正这些调用肯定会更容易进行故障排除。:)

此外,如果您计划使用字段长度(以整数形式写入文件),您将需要设置某种系统来读取长度,然后读取数据,并且您可能应该为每个字段设置一个长度场地。使用类绝对是处理这个问题的最简单方法。

编辑: 您可能想要使用结构和函数而不是类,或者您可以使用带有方法的类。没关系,两者都很简单。结构/功能:

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);
}
于 2010-05-01T16:09:40.727 回答