Как записать структуру в файл на языке C++?
Нужно создать приложение которое бы записывала структуру в файл и выводило из файла на экран.
Попытался это реализовать.
Но к сожалению не записывает всю структура в файл. Или некорректно записывает.
Вот сам код который я пытался реализовать:
#include "stdafx.h" #include "string.h" #include "stdio.h" #include #include using namespace std; void inputf(ifstream &f, char a[300], char b[300], char c[300], char d[300]); void outputf1(ofstream &f, char a[300], char b[300], char c[300], char s[40]); void main() // Основная функция < int c; setlocale(LC_ALL, "Russian"); cout > c; if (c == 2) < int const N = 3; int i,j=0; struct vvod < char fam[300]; char id[300]; char number[300]; >; vvod v[N]; for (i = 0; i < N; i++) < cout > v[i].fam; cout > v[i].id; cout > v[i].number; > ofstream f1; for (i = 0; i < N; i++) < outputf1(f1, v[i].fam, v[i].id, v[i].number, "writer.txt"); >> else if (c == 1) < char str[40];//Строковая переменная (для пути к файлу) cout > str; char v[900]; char q[300]; char w[300]; char e[300]; ifstream f; inputf(f,str,q,w,e); > > void outputf1(ofstream &f, char a[300], char b[300], char c[300], char s[40])//Функция для записи < f.open(s);//Открываем файл //Проверка успешности открытия файла: if (f.fail()) < cout f void inputf(ifstream &f, char a[300],char b[300], char c[300],char d[300] )//Функция для чтения < f.open(a);//Открываем файл //Проверка успешности открытия файла: if (f.fail()) < cout f >> b;//Читаем переменную из файла f >> c; f >> d; cout
Подскажите где накосячил.
- Вопрос задан более трёх лет назад
- 3390 просмотров
Как записать и считать структуру в файл на СИ
Всем добрый вечер, такая проблема, записываю структуру в файл, но при следующем запуске и чтении из файла, программа перестает работать. Также при удаление строчки 114 и 115 программа перестает работать, может кто подсказать почему?
#include #include #include #include using namespace std; typedef struct _date < int num; char* month; int year; >date; typedef struct _fio < char* fam; //Фамилия char* name; //Имя char* father; //отчество >fio; struct _deposid < int countName; fio client; date date; double sum; >; // Функция вывода счета void printClient(_deposid &client) < cout void sumLarge(_deposid *clients, int thisClient, int needSum, int countSum) < for (int i = 0; i < thisClient; i++ ) < if (clients[i].sum >needSum) < printClient(clients[i]); countSum++; >> if (countSum == 0) < cout countSum = 0; > void printNameLastname(_deposid *clients, int thisClient, char *firstname, char *lastname, char *father, int countSum) < for (int i = 0; i < thisClient; i++ ) < if (strcmp(clients[i].client.name, firstname) == 0 && strcmp(clients[i].client.fam, lastname) == 0 && strcmp(clients[i].client.father, father) == 0) < printClient(clients[i]); countSum++; >> if (countSum == 0) < cout countSum = 0; > // Функция создания нового клиента void newClient(_deposid &client) < char *userLastname = new char[100], *userFirstname = new char[100], *userFather = new char[100], *userMonth = new char[100]; // Ввод данных cout > userFirstname; client.client.name = new char[strlen(userFirstname)+1]; strcpy(client.client.name, userFirstname); cout > userLastname; client.client.fam = new char[strlen(userLastname)+1]; strcpy(client.client.fam, userLastname); cout > userFather; client.client.father = new char[strlen(userFather)+1]; strcpy(client.client.father, userFather); cout > client.date.num; cout > userMonth; client.date.month = new char[strlen(userMonth)+1]; strcpy(client.date.month, userMonth); cout > client.date.year; cout > client.sum; // Очистка памяти delete [] userLastname; delete [] userFirstname; > int main() < char *lastname = new char[100], *firstname = new char[100], *father = new char[100]; int n, thisClient = 0, numberFunction = 0, needSum, countSum = 0; _deposid *clients; char c; FILE *fp; fp=fopen("t.txt", "r+"); if (fp==NULL) < fclose(fp); fp=fopen("t.txt", "w+"); cout > n; clients = new _deposid[n]; // Создание массива структур > else < while((c = fgetc(fp)) != EOF) // При удалении этой и строчки ниже программа вообще не запускается putchar(c); while(fread(clients, sizeof(_deposid),1,fp)); // fputs("lol", fp); // fclose(fp); >cout > numberFunction; switch (numberFunction) < case 1: if (thisClient == n) < cout else < clients[thisClient].countName = thisClient + 1; newClient(clients[thisClient]); cout break; case 2: cout break; case 3: // Вывод счетов с суммой большей заданной cout > needSum; cout > firstname; cout > lastname; cout > father; cout > >

Отслеживать
задан 16 мая 2022 в 11:18
егор виктуров егор виктуров
3 2 2 бронзовых знака
1 ответ 1
Сортировка: Сброс на вариант по умолчанию
В принципе всё просто. Вы в файл сохраняете не все данные.
case 5: cout
Когда вы так пишете, в файл сохраняется сама структура. Т.е. в файл сохраняются не текстовые данные, кот. вы записывали в выделяемые через new буферы, а просто значение указателей char* month; и char* fam; char* name; char* father; . Для примера, проверьте значение sizeof(_deposid) - в размере структуры не будет размера того текста (фамилии, имени, отчества, названия месяца), которые вы вводили с клавиатуры.
А потом Вы загружаете из файла значение указателей, которые указывают в "никуда". Вам нужно написать свою функцию вывода Вашей структуры в файл. И свою функцию загрузки структуры из файла.
Существуют уже готовые библиотеки сериализации (вывода в поток и загрузки из потоков) объектов. Но для этой задачи проще написать свои функции.
Совет - каждое поле пишите отдельной строкой и считывайте построчно - так будет проще.
Ну и вот этот кусок:
fp=fopen("t.txt", "r+"); if (fp==NULL) < clients = new _deposid[n]; // Создание массива структур >else < while((c = fgetc(fp)) != EOF) // При удалении этой и строчки ниже программа вообще не запускается putchar(c); while(fread(clients, sizeof(_deposid),1,fp));
Как правильно написал @JohnDoe выделение памяти под массив структур делается только если файла не существует. Если он существует, память под массив не выделяется. И дальше у Вас 2 ошибки, первая из которых не дает состояться второй. Вторая ошибка - запись данных в невыделенную область памяти:
fread(clients, sizeof(_deposid),1,fp)
Здесь для clients память не выделена! А Вы пытаетесь записать туда что-то!
А первая ошибка не дает случиться второй - вот этими строками вы считываете весь файл.
while((c = fgetc(fp)) != EOF) putchar(c);
Дескриптор файла указывает на конец файла. Функция fread() не может ничего считать из файла и поэтому ничего не записывает в невыделенную память.
По вашей логике при записи массива структур в файл вам нужно сначала записать туда количество объектов в массиве, а потом - сами объекты. И считывать в таком же порядке:
- считать количество объектов,
- выделить под них память,
- считать сами объекты
Ещё один момент:
void newClient(_deposid &client) < char *userLastname = new char[100], *userFirstname = new char[100], *userFather = new char[100], *userMonth = new char[100]; . delete [] userLastname; delete [] userFirstname;
Выделили 4 массива, а освободили только 2. А в main() выделили и вообще не освободили. И зачем выделение через new() , если вы знаете размер буферов? Только чтобы память на куче была выделена? Стек выдержит ваши 400 байт, сделайте проще:
void newClient(_deposid &client)
Как записать структуру в файл в си
Есть у меня некая структура (struct).
Требуется создать файл, куда писать данные в виде этих структур. А также читать. А также перемещаться по файлу.
Как это сделать? (Плиз с ма-аленьким примером или в какую сторону копать).
Заранее спасибо.
Запись и чтение структур в/из файл(а)
| От: | IT | linq2db.com |
| Дата: | 11.10.02 04:19 | |
| Оценка: | 100 (18) +2 -2 | |
| #Имя: | FAQ.cpp.struct2file | |
Почему ламерский? Нормальный вопрос, который обычно встречается большинству программеров.
ПА>Есть у меня некая структура (struct).
ПА>Требуется создать файл, куда писать данные в виде этих структур. А также читать. А также перемещаться по файлу.
ПА>Как это сделать? (Плиз с ма-аленьким примером или в какую сторону копать).
Всё зависит от многих вещей, как всегда
Для начала давай объявим твою структуру:
struct mystruct < int i; char buf[20]; double d; >;
Теперь, допусти, нам нужно положить её в файл средствами C/C++.
Семейсво функций FILE рассматривать не будет в связи с её архаичносью, и начнём сразу с варианта, который не входит в стандарт, но присутствует во многих компиляторах.
#include #include #include #include #include struct mystruct < int i; char buf[5]; double d; >; int main(int argc, char* argv[]) < // открываем файл int fh = _open("file.dat",_O_RDWR | _O_BINARY); if (fh == -1) < // или при необходимости создаём новый fh = _creat("file.dat",_S_IREAD | _S_IWRITE); if (fh == -1) // не шмагла :xz: return 1; > // готовим структуру для записи mystruct ms; memset(&ms,0,sizeof ms); ms.i = 1; ms.d = 2; // позиционируемся в конец файла _lseek(fh,0,SEEK_END); // добавляем новую структуру _write(fh,&ms,sizeof ms); // позиционируемся в начало _lseek(fh,0,SEEK_END); // читаем первую записанную структуру _read(fh,&ms,sizeof ms); return 0; >
Эта программа открывает файл (либо создаёт его при необходимости) и добавляет в него новую структуру, затем читает первый экземпляр.
Всё казалось бы нормально, но если ты посмотришь размер созддаваемого файла, то он всегда будет кратен 24 байтам (вариант Visual C++), хотя размер структуры равен 4+5+8=17 байт. Это происходит потому, что компиляторы по умолчанию выравнивают размер структур в целях оптимизации. Следовательно, наша первая задача отменить это поведение по умолчанию. Стандартных средств сделать это нет, но как правило компиляторы содержат специальную опцию коммандной строки и/или прагму, позволяющую это делать.
Ещё одной неверной деталью в нашем примере является использование типа переменной int. Для разных версий операционных систем размер инта может быть разным и лучше явно указать размер используемого типа — short или long.
Изменим описание структуры:
#pragma pack(push,1) struct mystruct < long i; char buf[5]; double d; >; #pragma pack(pop)
Теперь запись в файл даст вполне ожидаемый результат.
Здесь можно отметить ещё одну деталь. В качестве строки я использовал массив char[5]. Использование классов типа CString std::string не приведёт ни к чему хорошему. Фактически ты сохранишь не саму строку, а содержимое класса, который её реализует. Допустим, класс CMyString реализован следующим образом:
class CMyString < public: int len; char *str; // . >;
Объявление такой структуры как
struct mystruct < long i; CMyString str; double d; >;
будет фактически соответствовать следующему варианту:
struct mystruct < long i; int str_len; char *str_str; double d; >;
Т.е. в месте, где ты ожидаешь строку будет указатель на буфер в памяти, который (в смысле не буфер, а указатель на него) ты благополучно и сохранишь в файле.
Теперь рассмотрим вариант с потоками. Вообще-то, лучше конечно использовать новую версию , но у меня она до сих не вызывает никакого доверия. По-этому, воспользуемся старым вариантом:
#include #include #pragma pack(push,1) struct mystruct < long i; char buf[5]; double d; >; #pragma pack(pop) int main(int argc, char* argv[]) < // создаём или открываем файл fstream f("file.dat",ios::binary|ios::in|ios::out); // готовим структуру для записи mystruct ms; memset(&ms,0,sizeof ms); ms.i = 1; ms.d = 2; // позиционируемся в конец файла f.seekp(0,ios::end); // добавляем новую структуру f.write((unsigned char*)&ms,sizeof ms); // позиционируемся в начало f.seekp(0,ios::beg); // читаем первую записанную структуру f.read((unsigned char*)&ms,sizeof ms); return 0; >
Ниже вариант использования Windows API вместо фуекций CRTL:
#include #pragma pack(push,1) struct mystruct < long i; char buf[5]; double d; >; #pragma pack(pop) int main(int argc, char* argv[]) < // создаём или открываем файл HANDLE fh = ::CreateFile( TEXT("file.dat"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); // готовим структуру для записи mystruct ms; memset(&ms,0,sizeof ms); ms.i = 1; ms.d = 2; // позиционируемся в конец файла ::SetFilePointer(fh,0,0,FILE_END); // добавляем новую структуру DWORD dw=0; ::WriteFile(fh,&ms,sizeof ms,&dw,NULL); // позиционируемся в начало ::SetFilePointer(fh,0,0,FILE_BEGIN); // читаем первую записанную структуру ::ReadFile(fh,&ms,sizeof ms,&dw,NULL); return 0; >
Еще можно привести вариант исользования класса CFile из MFC, но, в принципе, он будет не очень сильно отличаться.
Может я немного увлёкся, но главное чтобы было понятно
ЗЫ. Далше тебя ждут другие вопросы:
- Как узнать количество записанных структу в файле?
Правильный ответ — не вычислять это по размеру файла, а добавить в начало заголовок (специальную структуру), содержащую необходимую служебную информацию: фактический размер файла, версию формата, число записей, смещение к первому блоку и т.п. - Как добавлять записи переменной длины?
Можно к каждой записи добавить свой заголовок, описывающий её структуру. - Как удалять ненужные записи из файла?
Можно просто помечать их как удалённые, а в последствии организовать упаковку файла. Можно организовать список удалённых страниц и использовать их в дальнейшем вместо добавления новых в конец. - Как обеспечить совместный доступ к файлу из нескольких программ.
Блокировки, отдельный сервер доступа и ещё куча всяких вариантов. - Как сделать динамическую структуру записей в файле.
У-у-у.
Если нам не помогут, то мы тоже никого не пощадим.
Re[2]: Про файлы.
| От: | Панкратов Александр |
| Дата: | 11.10.02 04:43 |
| Оценка: |
Огромное спасибо, очень исчерпывающе.
IT>После всего этого возникает вполне законный вопрос — а может лучше сразу взять стандартную базу данных?
IT>Шутю я, шутю.
Если бы речь шла об обычных виндах — я бы так и сделал
Однако все происходит в WinCE. Да еще на обкоцанном варианте Casio. Поэтому с ADOCE возникают некоторые проблемы.
Re[2]: Переносимость short и long ?
| От: | Vi2 | http://www.adem.ru |
| Дата: | 11.10.02 04:52 | |
| Оценка: |
Здравствуйте IT, Вы писали:
IT>Ещё одной неверной деталью в нашем примере является использование типа переменной int. Для разных версий операционных систем размер инта может быть разным и лучше явно указать размер используемого типа — short или long.
Интересно, неужели для разных версий операционных систем размеры short или long, в отличие от int, одинаковы?
Насколько я помню, есть sizeof(short int)
Так что и использование short или long не даст переносимости.
Vita Выше головы не прыгнешь, ниже земли не упадешь, дальше границы не убежишь! © КВН НГУ
Re[3]: Про файлы.
| От: | orangy | http://twitter.com/orangy |
| Дата: | 11.10.02 06:19 | |
| Оценка: | 6 (1) | |
Здравствуйте Панкратов Александр, Вы писали:
IT>>После всего этого возникает вполне законный вопрос — а может лучше сразу взять стандартную базу данных?
ПА>Однако все происходит в WinCE. Да еще на обкоцанном варианте Casio. Поэтому с ADOCE возникают некоторые проблемы.
Тогда у тебя возникает еще ряд проблем:
— CE система юникодная, осторожнее со строками при записи и чтении
— не помню какой Endian на Casio (это кажется был MIPS), осторожнее с переносом файлов с win32
— нельзя игнорировать alignment, точнее он должен быть на 4 байта. MIPS не позволяет адресовать 32-битное число по невыровненному адресу
это важно, если ты собираешься читать массивами структур
I would recommend using WINAPI CreateFile, ReadFile, . functions тьфу блин, совсем зарапортавался.
Используй WINAPI CreateFile, ReadFile, . — в winCE другого может и не быть, лучше всего завернуть это дело в портабельную оболочку.
Всегда указывай полный путь до файла, в WinCE нет понятия "текущая директория", если нужно — возьми у текущего модуля.
TCHAR buf[_MAX_PATH+30];
GetModuleFileName(hInstance, buf, _MAX_PATH);
Если объёмы данных небольшие — используй XML. Была где-то библиотека портированная для CE, поищи.
Янус 1.0 alpha 10: Orangy
"Develop with pleasure!"
Re[3]: Переносимость short и long ?
| От: | Павел Кузнецов |
| Дата: | 11.10.02 08:13 |
| Оценка: |
Здравствуйте Vi2, Вы писали:
IT>>Ещё одной неверной деталью в нашем примере является использование типа переменной int. Для разных версий операционных систем размер инта может быть разным и лучше явно указать размер используемого типа — short или long.
Здесь IT был не вполне точен.
Vi2>Интересно, неужели для разных версий операционных систем размеры short или long, в отличие от int, одинаковы?
Не только для разных операционных систем, но и для разных компиляторов на одной операционной системе размеры short, long и int могут различаться.
Vi2>Насколько я помню, есть sizeof(short int)
Кроме указанного соотношения есть еще требования к минимальному диапазону представляемых значений:
short -32767 . . . +32767 (минимум 16 бит) int -32767 . . . +32767 (минимум 16 бит) long -2147483647 . . . +2147483647 (минимум 32 бита)
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Re[3]: Переносимость short и long ?
| От: | IT | linq2db.com |
| Дата: | 11.10.02 11:31 | |
| Оценка: |
Здравствуйте Vi2, Вы писали:
Vi2>Интересно, неужели для разных версий операционных систем размеры short или long, в отличие от int, одинаковы?
Ну если считать Windows 3.1 и Windows 95 разными версиями то да К тому же MS выпустила там чего-то 64 разрядное кажется, там уже и long поплывёт.
Vi2>Насколько я помню, есть sizeof(short int)
Vi2>Так что и использование short или long не даст переносимости.
Ладно придираться, я только обозначил проблему.
Если нам не помогут, то мы тоже никого не пощадим.
Re: Запись и чтение структур в/из файл(а)
| От: | AndrewS42 |
| Дата: | 06.06.05 06:58 |
| Оценка: |
Здравствуйте, IT, Вы писали:
IT>Всё зависит от многих вещей, как всегда
Это точно! Несмотря на то, что топику уже несколько лет, я хотел бы вставить свои 5 копеек в обсуждаемую тему, тем более, что эта тема находится в статьях сайта, а значит не имеет срока давности.
Наиболее правильным и переносимым (но медленным) будет вообще не сохранять в файл структуру целиком. Более того, не желательно даже int записывать в файл напрямую. Одна из причин уже была озвучена в топике: несовпадающие размеры int в разных компиляторах даже на одной платформе. Другая причина кроется в переносимости. Не факт, что ваша программа (или даже её отдельный модуль) никогда не переедут под UNIX. В отличие от Windows, UNIX существует на большом зоопарке платформ. Некоторые из них имеют big-endian представления чисел (первым идёт старший байт). Если на такой платформе сохранить int в файл как есть, а затем прочитать этот файл на Intel-платформе, то мы получим совершенно другое число. Например (пусть размер int будет 32 бита), если на big-endian сохранили 0x12345678, то в little-endian прочитаем 0x78563412.
Для большинства эти детали не существенны, так как не так уж и много программистов (надо признаться, и я в том числе) пишут сразу для нескольких платформ. Но, по крайней мере, задуматься о потенциальных проблемах переносимости надо.
Как же сохранять данные в файл, чтобы и файл, и программа его читающая были переносимы? Ответ уже был в этом топике: сохранять всё в xml или другом текстовом файле. Однако, если объём данных велик, и от двоичных данных никуда не деться, то сохранять все данные следует побайтно. Пример сохранения 32-битного int (предполагаем, что система, где char имеет размер, не равный 8 бит, нам не попадётся):
#include const char filename[] = "file.dat"; void read_int(FILE* f, int* d) < unsigned char buf[4]; unsigned char* p = buf; fread(buf, sizeof(buf), 1, f); // portable *d = *p++; *d += *p++ // fread(d, sizeof(*d), 1, f); // not portable > // read_int void write_int(FILE* f, int d) < unsigned char buf[4]; unsigned char* p = buf; *p++ = d & 0xff; *p++ = (d >> 8) & 0xff; *p++ = (d >> 16) & 0xff; *p = (d >> 24) & 0xff; fwrite(buf, sizeof(buf), 1, f); // portable // fwrite(&d, sizeof(d), 1, f); // not portable > // write_in void help() < fprintf(stderr, "Usage: fileio \n" ); exit(1); > // help() int main(int argc, char *argv[]) < const int data = 0x12345678; FILE* fi; FILE* fo; int tmp; char err_msg[255]; if (argc != 2) help(); if (! strcmp(argv[1], "w")) < fo = fopen(filename, "w"); if (! fo) < sprintf(err_msg, "Can not open file '%s'", filename); perror(err_msg); exit(1); > write_int(fo, data); fclose(fo); > else if (! strcmp(argv[1], "r")) < fo = fopen(filename, "r"); if (! fo) < sprintf(err_msg, "Can not open file '%s'", filename); perror(err_msg); exit(1); > read_int(fo, &tmp); fclose(fo); printf("Readed %#08x. Must be %#08x\n", tmp, data); > else help(); return 0; > // main()
Если гложут вопросы быстродействия, особенно в свете того, что big-endian систем не много и ради этой редкости мы замедляем считывание файлов, то необходимо ввести условную компиляцию: на little-endian системе читать int целиком, на big-endian – побайтно. Опять же, нельзя забывать про отличия размера int на разных платформах.
Хочу отметить, что я далеко не гуру в этом вопросе, и все мои замечания основаны лишь на изучении и портировании Open source ПО на компьютер RM200 (RISC-процессор R4000 (big-endian), ОС SINIX).
Всего Вам
Андрей
Re[2]: Запись и чтение структур в/из файл(а)
| От: | MaximE |
| Дата: | 06.06.05 07:20 |
| Оценка: |
[]
> Как же сохранять данные в файл, чтобы и файл, и программа его читающая были переносимы? Ответ уже был в этом топике: сохранять всё в xml или другом текстовом файле. Однако, если объём данных велик, и от двоичных данных никуда не деться, то сохранять все данные следует побайтно. Пример сохранения 32-битного int (предполагаем, что система, где char имеет размер, не равный 8 бит, нам не попадётся):
Автор: MaximE
Дата: 02.04.05
Автор: MaximE
Дата: 06.04.05
--
Maxim Yegorushkin
Как записать структуру в файл в си
p51x, у меня over 10 переменных в структуре, паревно, хотя, похоже, придется делать так.
pproger, при подходе к кульминационному моменту вылетает с Segmentation fault. (файл открывал с "wb")
FILE * q; q = fopen("1", "bw"); fwrite(&var,sizeof(var),1,q);
у вас написано не wb а bw тэто во превых. во вторых
данный способ неверен, т.к. sizeof(char*) будет равен одному, запишуться one,two,ten и один байт из q. Если в структуре есть указатели то надо записывать следующим образом
fwrite(&var.one,sizeof(int),1,f); fwrite(&var.two,sizeof(int),1,f); fwrite(&var.ten,sizeof(int),1,f); fwrite((void*)var.q,strlen(var.q),1,f);
Регистрация: 15.02.2010
Сообщений: 15,655
Ну. не одному, а 4, скорее всего. все-таки указатель.
СтарожилДжуниор
Регистрация: 19.07.2009
Сообщений: 3,336
| 2 pproger Так запишется указатель на строку, а не сама она. |
я передаю указатель на структуру, а не на строку + размер структуры.
#include #include typedef struct _tagStruct < int a; int b; char name[64]; >st; int main() < st s; FILE* f; s.a = 1; s.b = 2; strcpy(s.name, "myname"); f = fopen("./file", "w"); fwrite(&s, sizeof(s), 1, f); fclose(f); memset(&s, 0, sizeof(s)); f = fopen("./file", "r"); fread(&s, sizeof(s), 1, f); fclose(f); printf("%d %d %s\n", s.a, s.b, s.name); return 0; >
typedef struct some< int one,two,ten; char *q; >lol;
нельзя просто так записать целиком структуру. действительно, по одному полю, либо убери указатель из структуры
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay
My other car is cdr.
Q: Whats the object-oriented way to become wealthy?
A: Inheritance
Последний раз редактировалось pproger; 28.02.2010 в 23:11 .
Участник клуба
Регистрация: 29.10.2009
Сообщений: 1,456
fwrite(&s, sizeof(s), 1, f); fread(&s, sizeof(s), 1, f);
и что это такое? в файл запишется фиг знает что, но не 1 2 myname
может быть всё-таки так будет правильно
fprintf(f,"%d %d %s",s.a,s.b,s.name); fscanf(f,"%d%d%s",&s.a, &s.b, &s.name);
СтарожилДжуниор
Регистрация: 19.07.2009
Сообщений: 3,336
2NiCola999
| и что это такое? в файл запишется фиг знает что, но не 1 2 myname |
в моем случае в файл запишется память структуры, которую потом можно считать в такую же структуру
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay
My other car is cdr.
Q: Whats the object-oriented way to become wealthy?
A: Inheritance
Форумчанин
Регистрация: 03.01.2010
Сообщений: 229
в файл запишеться как раз что надо.
00 00 00 01 | 00 00 00 02 | 6D 79 6E 61 6D 65
в том дело, что int 4 байта, посчитайте выше. откройте редактором и сами увидете как отображаеться код аски символа 0x01 и 0x02 (это то, что для вас не так. Зависит от поставленой задачи! Если вам надо чтобы отображался текст - делайте как выше написали вы.
Тогда считывайте так
fscanf(f,"%d%d%s",&s.a, &s.b, s.name);
Без амперсанта перед s.name
и уберите пробелы
fprintf(f,"%d%d%s",s.a,s.b,s.name);