Porównaj ceny domen i usług IT, sprzedawców z całego świata

Jak mogę zapisać strukturę do pliku?


Próbowałem to znaleźć w wielu miejscach i nie mogę dowiedzieć się, dlaczego Fwrite nie działa.
Gdybym miał strukturę ze 100 polami, nie chciałbym używać fprintf ze 100 specyfikatorami formatu.
struct emp
{
char name[15];
int age;
int salary;
char address[30];
};
int main()
{ char str[60];
struct emp emp1[5] = {{"Yoda",23,45000,"Asia"},{"Darth",34,2344,"NAmerica"},{"Jabba",22,5566,"Africa"},{"Luke",33,3399,"SAmerica"},{"Laya",44,6677,"Europe"}}; FILE *fp;
fp = fopen("C:/.../sampleText.txt","w");`
int i=0;
for(i=0; i<5; i++)
{ fwrite(&emp1[i],sizeof(emp1[i]),1,fp);//fprintf(fp,"%s, %d, %d, %s\n",&emp1[i].name,emp1[i].age,emp1[i].salary,emp1[i].address);
} fclose(fp);
getch();
}

Zaproszony:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Istnieją dwie odpowiedzi:
  • Naprawdę działa, jeśli wszystko jest poprawnie skonfigurowane, a przesyłanie zapisanych danych na inne maszyny nie stanowi problemu.
  • To nie działa, jeśli masz dowolną z dużej liczby typowych funkcji w swoich strukturach danych lub jeśli musisz przenieść dane z jednego typu maszyny (powiedzmy z maszyny Intela) na inny typ (powiedzmy, PowerPC lub SPARC).

W twojej przykładowej strukturze nie masz wskaźników, więc możesz zapisać strukturę dosłownie do pliku, a następnie w kolejnym wywołaniu programu działającego na tym samym komputerze (typie) możesz go odczytać i zobaczyć te same dane .
Jeśli jednak twoja struktura zawiera wskaźniki, nie możesz sensownie zapisać struktury na dysk. Wskaźniki w jednym wywołaniu programu nie mogą mieć znaczenia w innym wywołaniu programu. Gdybyś miał przesyłać dane między maszyną little-endian (Intel) a maszyną typu big-endian (PowerPC, SPARC), musiałbyś użyć neutralnego dla platformy sposobu dostępu do danych; zwykłe zapisanie danych na dysku nie zadziała.
Tak więc tam, gdzie przenośność nie jest problemem, ten kod powinien działać - Unix lub Windows. Używa argumentów
"wb"
i
"rb"
dla
fopen ()
, ponieważ dane są danymi binarnymi, a nie zwykłym tekstem. b jest opcjonalne, ale nieszkodliwe na Uniksie; jest krytyczny w systemie Windows. Kod naprawia również nazwę pliku na
sampledata.bin
, dzięki czemu można go uruchomić na dowolnej platformie, zapisując w bieżącym katalogu. Zapisuje dane; następnie odczytuje dane; następnie porównuje odczytane dane z zapisanymi danymi, zgłaszając wszelkie problemy. Jeśli program nic nie mówi, wszystko jest w porządku.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>struct emp
{
char name[15];
int age;
int salary;
char address[30];
};int main(void)
{
char const filename[] = "sampledata.bin";
struct emp emp1[5] =
{
{ "Yoda", 23, 45000, "Asia" },
{ "Darth", 34, 2344, "N America" },
{ "Jabba", 22, 5566, "Africa" },
{ "Luke", 33, 3399, "S America" },
{ "Leia", 44, 6677, "Europe" },
};
struct emp emp2[5];
FILE *ifp;
FILE *ofp;
int i; ofp = fopen(filename, "wb");
if (ofp != 0)
{
if (fwrite(emp1, sizeof(emp1), 1, ofp) != 1)
{
fprintf(stderr, "Failed to write to %s\n", filename);
exit(1);
}
fclose(ofp);
} ifp = fopen(filename, "rb");
if (ifp != 0)
{
if (fread(emp2, sizeof(emp2), 1, ifp) != 1)
{
fprintf(stderr, "Failed to read from %s\n", filename);
exit(1);
}
fclose(ifp);
} for (i = 0; i < 5; i++)
{
if (emp1[i].age != emp2[i].age ||
emp1[i].salary != emp2[i].salary ||
strcmp(emp1[i].name, emp2[i].name) != 0 ||
strcmp(emp1[i].address, emp2[i].address) != 0)
printf("Difference in record %d\n", i);
} return 0;
}

Zawartość pliku
sampledata.bin
:
0x0000: 59 6F 64 61 00 00 00 00 00 00 00 00 00 00 00 00 Yoda............
0x0010: 17 00 00 00 C8 AF 00 00 41 73 69 61 00 00 00 00 ........Asia....
0x0020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0030: 00 00 00 00 00 00 00 00 44 61 72 74 68 00 00 00 ........Darth...
0x0040: 00 00 00 00 00 00 00 00 22 00 00 00 28 09 00 00 ........"...(...
0x0050: 4E 20 41 6D 65 72 69 63 61 00 00 00 00 00 00 00 N America.......
0x0060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0070: 4A 61 62 62 61 00 00 00 00 00 00 00 00 00 00 00 Jabba...........
0x0080: 16 00 00 00 BE 15 00 00 41 66 72 69 63 61 00 00 ........Africa..
0x0090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00A0: 00 00 00 00 00 00 00 00 4C 75 6B 65 00 00 00 00 ........Luke....
0x00B0: 00 00 00 00 00 00 00 00 21 00 00 00 47 0D 00 00 ........!...G...
0x00C0: 53 20 41 6D 65 72 69 63 61 00 00 00 00 00 00 00 S America.......
0x00D0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x00E0: 4C 65 69 61 00 00 00 00 00 00 00 00 00 00 00 00 Leia............
0x00F0: 2C 00 00 00 15 1A 00 00 45 75 72 6F 70 65 00 00 ,.......Europe..
0x0100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0x0110: 00 00 00 00 00 00 00 00 ........
0x0118:
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Nie określasz, co masz na myśli, mówiąc
fwrite nie działa
, ale zakładam, że pracujesz w systemie Windows, w takim przypadku musisz określić
"wb"
na < code> fopen . Domyślnie w systemie Windows jest napisane w
trybie tekstowym
(czyli
"wt"
).
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

nie jest dobrym pomysłem zapisywanie
struct
do pliku lub gniazd w takiej postaci, w jakiej jest. To zachęcający kompleks do rozwiązywania problemów. najlepszym podejściem jest użycie serializacji przed napisaniem. Ponadto, jak wskazał powyżej Jim, pamiętaj, aby otworzyć plik w formacie binarnym.
Spójrz na to pytanie i odpowiedzi. Twoje pytanie ma całkiem dobrą odpowiedź i wyjaśnienie.

Przechodzenie struktury przez gniazda w C
https://coderoad.ru/1577161/
Anonimowy użytkownik

Anonimowy użytkownik

Potwierdzenie od:

Serializacja danych nie jest prostym zadaniem. Jak zauważyli inni, w niektórych przypadkach jest możliwe zapisanie zawartości twojej struktury na dysku jako danych binarnych. To najłatwiejszy sposób pisania, ale jest mało prawdopodobne, aby był stabilny. Za każdym razem, gdy rekompilujesz kod, może to potencjalnie zmienić format zapisu i odczytu danych.
Najlepiej jest używać standardowego formatu wymiany danych, takiego jak CSV, XML lub JSON. Istnieje wiele narzędzi do korzystania z tych formatów, więc powinieneś rozważyć użycie jednego z nich.

Aby odpowiedzieć na pytania, Zaloguj się lub Zarejestruj się