Запись структуры в файл на C - PullRequest
0 голосов
/ 23 июля 2010

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

Вот немного больше деталей моего кода:

У меня есть код, который читает и записывает список имени элемента и кодав файл (file.txt).Код использует концепцию связанного списка для чтения и записи данных.Данные сохраняются в объекте структуры и затем записываются в файл с помощью fwrite.

Код работает нормально.Но мне нужно записать читаемые данные в текстовый файл.

Теперь file.txt выглядит следующим образом:

* 㡸 䍏 䥔 䥆 㘸 䘠 㵅 㩃 䠀 \ 䵏 㵈䑜 㵅 㡸 䍏 䥔 䥆 㘸 䘠 \ 㵅 㩃 䠀 䵏 㵈 䑜 㵅 㡸 䍏 䥔 䥆 㘸 䘠 㵅 㩃 䠀 䵏 㵈 \ 䑜 㵅 㡸 䍏 䥔 䥆 㘸 䘠 㵅 㩃 䠀 䵏 㵈 䑜 㵅 㡸 䍏 䥔 \ 䥆 㘸 䘠101 㩃 䠀 䵏 㵈

Я ожидаю, что файл должен быть таким,

Карандаш Aaaa
Таблица BBD
Ручка CCCC
Блокнот NNNN

Вот фрагмент:

struct Item
{
char itemname[255];
char dspidc[255];
struct Item *ptrnext;
};

  // Writing into the file
printf("\nEnter Itemname: ");
gets(ptrthis->itemname);
printf("\nEnter Code: ");
gets(ptrthis->dspidc);
fwrite(ptrthis, sizeof(*ptrthis), 1, fp);

  // Reading from the file
while(fread(ptrthis, sizeof(*ptrthis), 1, fp) ==1)
{
  printf("\n%s %s", ptrthis->itemname,ptrthis->dspidc);
  ptrthis = ptrthis->ptrnext;
}

Ответы [ 3 ]

1 голос
/ 23 июля 2010

Запись размера массива 255 байт приведет к записи 255 байт в файл (независимо от того, что вы ввели в этот массив).Если вам нужна только «текстовая» часть этого массива, вам нужно использовать средство, которое обрабатывает нулевые терминаторы (т. Е. printf, fprintf, ...).

Считывание становится более сложным, поскольку вынужно настроить идею значения часового, которое представляет конец строки.

Это ничего не говорит о том факте, что вы пишете значение указателя (инициализированный или нет), который не будет иметь никакого контекста или достоверности при следующем чтении.Указатели (т. Е. Области памяти) имеют применение только внутри текущего выполняемого процесса.Попытка использовать адрес памяти одного процесса в другом, безусловно, является плохой идеей .

1 голос
/ 23 июля 2010

The code works fine

не совсем:

a) вы выгружаете необработанное содержимое структуры в файл, включая указатель на другой экземпляр, если «Item».вы не можете ожидать, что вы прочитаете указатель с диска и будете использовать его так же, как вы используете ptrthis = ptrthis->ptrnext (я имею в виду, это работает, как вы «используете» его в данном фрагменте, но только потому, что этот фрагмент вообще ничего не делает значимым).

b) вы записываете в файл 2 * 255 байт потенциального мусора.причина, по которой вы видите эти странно выглядящие «блоки» в вашем файле, заключается в том, что вы записываете на диск все 255 байтов itemname и 255 байтов dspidc, включая завершающие \0 (которые являются блоками, в зависимости отв вашем редакторе).настоящая «строка» - это что-то значимое в начале либо itemname, либо dspidc, за которым следует \0, за которым следует то, что было в памяти раньше.

термин, который вам нужно найти, ичтение о называется сериализация , уже есть некоторые библиотеки, которые решают задачу сброса структур данных на диск (или сеть или что-то еще) и считывания их обратно, например TPL .

0 голосов
/ 23 июля 2010

Прежде всего, я бы сериализировал только данные, а не указатели.

Тогда, на мой взгляд, у вас есть 2 варианта:

  1. написать синтаксический анализатор для вашего синтаксиса(например, с yacc)
  2. использовать формат вывода данных, такой как механизм сериализации rmi.

Извините, я не могу найти онлайн-документы, но знаю, что у меня есть грамматика на бумаге.Оба эти решения будут независимы от платформы, будь то с прямым или прямым порядком байтов.

...