Я пытаюсь записать структуру в файл, а затем прочитать структуру в динамически выделяемой памяти. Если этот алгоритм вообще работает, я не уверен насчет функции fread ... Может ли он прочитать все структуры в файле, написанном таким образом, и сохранить их в * ptr, чтобы я мог получить к нему доступ из памяти? Есть способ сделать это лучше?
typedef struct num {
int num1;
int num2;
}NR;
void write() {
int successfullywritten;
FILE *f;
struct num nr;
f = fopen("dat.txt", "a");
printf("Enter first number\n");
scanf("%d", &nr.num1);
printf("Enter second number\n");
scanf("%d", &nr.num2);
successfullywritten=fwrite(&nr, sizeof num, 1, f);
printf("Succesfully written: %d\n", successfullywritten);
fclose(f);
}
void read() {
int size, entrys,i,successfullyread;
FILE *f;
f = fopen("dat.txt", "r");
struct num *ptr;
fseek(f, 0L, SEEK_END);
size = ftell(f);
printf("\nSize of file dat.txt: %d\n", size);
entrys = size / sizeof(num);
ptr = (num*)malloc(entrys * sizeof(num));
successfullyread=fread(ptr, sizeof(num), entrys, f);
printf("sucessfully Read: %d\n", successfullyread);
for (i = 0;i < entrys; i++) {
/*fread((ptr+i), sizeof(ptr), 1, f);*/
printf("%d ", (*(ptr)).num1);
printf("%d\n", (*(ptr)).num2);
}
printf("\n");printf("\n");
fclose(f);
}
int main() {
int n;
while(1){
printf("Chooose action:\n1) write to file\n2) read from file:\n");
scanf("%d", &n);
switch (n) {
case 1:
write();
break;
case 2:
read();
break;
}
}
return 0;
}
Вы заинтересованы в хранении значений элементов структуры в файле или в сохранении самой структуры? В любом случае, подход список может лучше служить вашим интересам.
В идеале, храните в памяти только то, что требуется для текущей обработки, если вы не знаете, что это понадобится вам позже. И у вас есть функции возвращаться, значение, указывающее на любую ошибку, вместо Распечатать, что.





Во-первых, есть много простых опечаток, таких как
entrys = size / sizeof(num); должен быть
entrys = size / sizeof(struct num);ptr = (num*)malloc(entrys * sizeof(num)); должен быть ptr = malloc(entrys * sizeof(struct num));. Избегайте кастинга результата malloc().Во-вторых, обнаружив size, вы забыли переместить f в начало файла. например, для
fseek(f, 0L, SEEK_END);
size = ftell(f);
fseek(f, 0L, SEEK_SET); /* you forgot to add this */
В-третьих, вы записываете данные в файл, используя fwrite(), используйте ab вместо режима a.
& при чтении с использованием fread() используйте rb вместо r.
Также после чтения из файла вам необходимо освободить ptr, чтобы избежать утечки памяти.
free(ptr);
Вот пример кода
typedef struct num {
int num1;
int num2;
}NR;
void my_write(void) {
int successfullywritten;
FILE *f;
struct num nr;
f = fopen("dat.txt", "ab");
printf("Enter first number\n");
scanf("%d", &nr.num1);
printf("Enter second number\n");
scanf("%d", &nr.num2);
successfullywritten=fwrite(&nr, sizeof(nr), 1, f);
printf("Succesfully written: %d\n", successfullywritten);
fclose(f);
}
void my_read(void) {
int size, entrys,i,successfullyread;
FILE *f;
f = fopen("dat.txt", "rb");
struct num *ptr;
fseek(f, 0L, SEEK_END);
size = ftell(f);
fseek(f, 0L, SEEK_SET);
printf("\nSize of file dat.txt: %d\n", size);
entrys = size / sizeof(struct num);
ptr = malloc(entrys * sizeof(struct num));
successfullyread=fread(ptr, sizeof(struct num), 2, f);
printf("sucessfully Read: %d\n", successfullyread);
for (i = 0;i < entrys; i++) {
/*fread((ptr+i), sizeof(ptr), 1, f);*/
printf("%d ", ptr[i].num1);
printf("%d\n", ptr[i].num2);
}
free(ptr);
printf("\n");printf("\n");
fclose(f);
}
int main(void) {
int n;
while(1){
printf("Chooose action:\n1) write to file\n2) read from file:\n");
scanf("%d", &n);
switch (n) {
case 1:
my_write();
break;
case 2:
my_read();
break;
}
}
return 0;
}
Вы уверены, что заявление size = ftell(f); дает то, что необходимо? (с учетом его последующего использования)
Нет, я не уверен. Во-первых, файл содержит двоичные данные, поэтому я сомневаюсь в этой формуле entrys = size / sizeof(struct num);
Да, у меня тоже есть такие же сомнения. Не стесняйтесь редактировать, если это необходимо.
Поскольку ftell() возвращает long, long size может работать с большими файлами, которые не работают с int size.
на самом деле это не .txt, это .dat