читать структуру из двоичного файла с указателем на память - PullRequest
0 голосов
/ 15 мая 2019
struct st {
        char *p;
        int len;
};

это структура, которую мне нужно записать в двоичный файл вместе со строкой, которая сохраняется в

char *p

Я должен написать двоичный файл с данными массива символов. После записи в двоичный файл. Должен также иметь возможность читать его в той же структуре из двоичного файла.

Я пытался использовать FSEEK_END, чтобы получить размер двоичного файла, и делал fread в соответствии с размером файла, но это не сохранение строки. Пожалуйста, предложите. Любая помощь / предложение / указатель будет оценен.

спасибо заранее.

пример кода:

 struct st {
         char *p;
         int len; 
 };

 struct st varr;
 varr.len = 100;
 varr.p = new char[gen];
 strcpy(varr.p, "Hello World");

 FILE *p;
 p=fopen("address","wb");
 fwrite(&varr,sizeof(struct st),1,p);
 fclose(p); 

это напишет мне указатель на двоичный файл. Но я хочу написать здесь всю строку, но дело в том, что это должно быть сделано с одним fwrite.

Ответы [ 5 ]

4 голосов
/ 15 мая 2019

Нет смысла записывать это в двоичный файл.Достаточно текстового файла.

Однако, если это ваше домашнее задание (или около того), я предлагаю вам выполнить следующее:

  • запишите длину в виде целого числа;

  • запись len байтов строки.Сюда не входит завершающий ноль.

При чтении обратно:

  • чтение целой длины;

  • выделить память этой длины плюс один байт

  • прочитать строку в эту память и добавить завершающий ноль .

Заполните вашу структуру этой длиной и указателем на выделенную память.


В ваших комментариях вы продолжаете итерацию, которую вы хотите читать и писать за один шаг. С вашей текущей структурой данных это невозможно , потому что строка символов всегда будет где-то в памяти, а fwrite может записывать только непрерывный блок памяти.

Однако вы бы измениливаша структура данных:

struct st{
    char p[128];
    int len;
};

, тогда вы сможете писать и читать за один раз, потому что теперь структура является непрерывным блоком памяти.Но теперь строка ограничена этими 128 байтами (или любым другим размером, который вы делаете).

1 голос
/ 15 мая 2019

Я бы предложил сначала сохранить strlen (p), а затем все символы, указанные в char * p. Если вы попытаетесь переписать структуру как есть, вы получите (в файле) значение для адреса, которое будет преобразовано в первый символ. Вы не хотите сохранить адрес 1-го символа?

0 голосов
/ 16 мая 2019

Я пробовал много способов, но ответ @kiran Biradar мне очень помог. отсюда отображение рабочего кода здесь.

WriteBinaryFile.cpp

    struct st_wrap {
            int len;
            int crc;
            char p[0]; 
    };


    int main ()
    {
            char p[100] = "Hello World";
            struct st_wrap *temp= (struct st_wrap*) malloc (sizeof (struct st_wrap ) + strlen(p)+1);
            temp->len = strlen(p);
            temp->crc = 400;
            strcpy(temp->p,p);
            cout << temp->p << endl;
            cout << temp->len << endl;
            cout << temp->crc << endl;

            FILE *p1;
            p1=fopen("binary.dat","wb");
            fwrite(temp,sizeof(struct st_wrap)+strlen(p),1,p1);
            fclose(p1);

    }

ReadBinaryFile.cpp

struct st_wrap {
        int len;
        int crc;
        char p[0];
};


int main ()
{
        struct st_wrap *vw;
        FILE *f=fopen("binary.dat","rb");
        fseek(f, 0, SEEK_END);
        long int filesize = ftell(f);
        fseek(f, 0, SEEK_SET);
        vw = (struct st_wrap*) malloc (filesize);
        fread(vw,filesize,1,f);
        cout << vw->len << endl;
        cout << vw->p << endl;
        cout << vw->crc << endl;
        return 0;
}
0 голосов
/ 15 мая 2019

Если вы записали длину и строку в двоичный файл:

FILE* fp = fopen("file.bin", "wb");

/* writing */
st str = { .p = "foo", .len = 3 };
fwrite((char*)(&str.len), sizeof(str.len), sizeof(str.len), fp);
fwrite(str.p, str.len, str.len, fp);

Теперь вы можете (в другом контексте) считывать содержимое из файла в объект struct:

FILE* fp = fopen("file.bin", "rb");
st str;
/* read length */
fread((char*)&str.len, sizeof(str.len), sizeof(str.len), fp);
/* allocate enough space */
str.p = malloc((str.len + 1) * sizeof(char));
/* read string */
fread(str.p, str.len + 1, str.len + 1, fp);

Не забудьте освободить память, когда закончите с p:

free(str.p);
0 голосов
/ 15 мая 2019

Если вас так беспокоит отсутствие двух fwrite, вы можете иметь структуру-обертку с массивом нулевой длины.

 struct st_wrap {
         int len; 
         char p[0];
 };

struct st_wrap *temp= malloc (sizeof (struct st_wrap ) + strlen(varr.p)+1);
temp->len = strlen(varr.p);

//Copy the data
strcpy(temp->p,varr.p);

//Then write it to file
fwrite(temp,sizeof(struct st_wrap)+strlen(varr.p),1,p);
...