Существует несколько проблем с вашим текущим кодом. До достижения этого вопроса структуры, вы, кажется, путают значение возврата из write
и fwrite
с:
fd=fwrite(my_info, sizeof(_my_info), 1, fp);
if (fd<0)
printf("Error while writing\n");
fwrite
возвращаемого значение типа size_t
. Он может никогда быть менее 0
. Если вы скомпилируете с предупреждениями (например, -Wall -Wextra
), вы всегда будете получать предупреждение о сравнении, всегда проверяя ложь.
Что касается места для вашей структуры, почему вы объявляете указатель? Если у вас нет какой-либо основной причины в вашем примере для объявления указателя, просто объявите статический экземпляр структуры, чтобы хранилище было автоматически зарезервировано. Если вы объявляете указатель, необходимо затем выделить пространство (например, _my_info *my_info = malloc (sizeof *my_info);
или _my_info *my_info = calloc (1, sizeof *my_info);
)
Для примера, кроме прохождения через осуществление динамического распределения, нет никаких причин, чтобы объявить указатель, просто объявить экземпляр. Ниже приведен краткий пример использования экземпляра и записи/чтения значений из файла.(примечание: комментарии относительно int main()
- и изменение имени файла по умолчанию для /tmp/info.bin
):
#include <stdio.h>
#define FILEE "/tmp/info.bin"
typedef struct {
int i;
int j;
int k;
int l;
} _my_info;
/* main is type 'int', has arguments and returns a value */
int main (int argc, char **argv)
{
_my_info my_info, my_info2; /* static instances */
/* write to given filename, or FILEE (default) */
FILE *fp = fopen (argc > 1 ? argv[1] : FILEE, "wb");
if (!fp) {
fprintf (stderr, "error: file open failed '%s'.\n", argv[1]);
return 1;
}
my_info.i = 100;
my_info.j = 300;
my_info.k = 200;
my_info.l = 400;
if (fwrite (&my_info, sizeof my_info, 1, fp) < 1) {
fprintf (stderr, "error: write to '%s' failed\n",
argc > 1 ? argv[1] : FILEE);
return 1;
}
if (fclose(fp) == EOF) goto errclose;
printf ("\n values written to : %s\n", argc > 1 ? argv[1] : FILEE);
/* reopen file for reading, read values into my_info2 */
fp = fopen (argc > 1 ? argv[1] : FILEE, "rb");
if (fread (&my_info2, sizeof my_info2, 1, fp) < 1) {
fprintf (stderr, "error: read from '%s' failed\n",
argc > 1 ? argv[1] : FILEE);
return 1;
}
if (fclose(fp) == EOF) goto errclose;
printf (" values read from : %s\n\n", argc > 1 ? argv[1] : FILEE);
printf (" my_info2.i : %d\n my_info2.j : %d\n"
" my_info2.k : %d\n my_info2.l : %d\n\n",
my_info2.i, my_info2.j, my_info2.k, my_info2.l);
return 0;
errclose:
fprintf (stderr, "error: EOF returned on stream close.\n");
return 1;
}
Выход
$ ./bin/struct_write
values written to : /tmp/info.bin
values read from : /tmp/info.bin
my_info2.i : 100
my_info2.j : 300
my_info2.k : 200
my_info2.l : 400
Позвольте мне знать, если у вас есть дополнительные вопросы, и пусть я знаю, если у вас есть неотразимая необходимость использовать указатель на структуру, и я рад помочь вам в дальнейшем.
Если вы пишете на '* my_info', не выделяя что-то во-первых, это неопределенное поведение. Зачем вам нужен указатель? Почему бы просто не использовать стек и объявить '_my_info my_info'? – e0k
Не работает. Кажется, похоже, что он работает. Это может сломаться позже. –
3 примечания; 1 - пространство имен * struct * и * global namespace * являются отдельными, поэтому вы можете сделать 'typedef struct my_info {...} my_info;' без конфликта и 2, вы также можете просто объявить typedef только для этой структуры 'typedef struct {...} my_info; 'и 3, вы можете просто объявить статический экземпляр в своем коде (например,' _my_info my_info; 'и пробел будет зарезервирован, вы должны использовать оператор * dot * (например,' my_info.i = 100; 'и т. Д.) –