Форум программистов, компьютерный форум, киберфорум
Наши страницы

C для начинающих

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 29, средняя оценка - 4.83
leon91
1 / 1 / 0
Регистрация: 15.12.2012
Сообщений: 6
#1

Запись и чтение бинарного файла - C (СИ)

15.12.2012, 03:43. Просмотров 4591. Ответов 12
Метки нет (Все метки)

Доброго времени суток!

Уже какой час бьюсь над проблемой и не могу никак решить ее

1. Нужно пропарсить данные из текстового файла input.txt следующего формата:

Bari; Nolo acerbam sumere ; 20; 150; 5; 100;
Taranto; Nolo acerbam sumere; 20; 150; 5; 101;
Ancona; Nolo acerbam sumere; 20; 150; 5; 102;
Roma; Nolo acerbam sumere; 20; 150; 5; 103;
Milano; Nolo acerbam sumere; 20; 150; 5; 104;
.....

2. Внести их в структуру, записать в бинарный файл и вывести на экран.

3. Прочесть и отобразить полученный бинарный файл.
Проблема возникает при попытке чтения из файла. Не могу понять, где я ошибаюсь. Надеюсь на вашу помощь.

Листинг программы:


C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdio.h>
#include <stdlib.h>
 
#define inputfName "input.txt"
#define outputfName "output.txt"
 
typedef struct
{
    char city[40]; // citta'
    char hotelName[40]; // nome di albergo
    int room1; // numero di stanze singole
    int room2; // numero di stanze doppie
    float room1Cost; // costo di una stanza singola
    float room2Cost; // costo di una stanza doppia
} Alberghi;
 
 
void parsingToStruct (FILE *alfa, FILE *beta);
void visualizza (FILE *beta);
 
 
int
main()
{
FILE *alfa, *beta;
 
parsingToStruct (alfa, beta);
visualizza (beta);
}
 
/* Модуль парсинга и создания бинарного файла */
 
void 
parsingToStruct (FILE *alfa, FILE *beta)
{
Alberghi albergo1;
int n=0;
 
alfa=fopen(inputfName,"r");
beta=fopen(outputfName, "wb");
 
if(alfa==NULL)
    printf("Errore");
 
else {
    
    rewind(alfa);
 
    while(fscanf(alfa,"%[^;]; %[^;]; %d; %f; %d; %f;\n",albergo1.city,albergo1.hotelName,&albergo1.room1, &albergo1.room1Cost,&albergo1.room2,&albergo1.room2Cost)!=EOF){
        fwrite(&albergo1, sizeof(Alberghi), n, beta);           
        printf("\n[%d] %s %s %d %.2f %d %.2f", n, albergo1.city,albergo1.hotelName,albergo1.room1, albergo1.room1Cost,albergo1.room2,albergo1.room2Cost);
        n++;
        }
                
    fclose(alfa);
    fclose(beta);
    
printf("\n\n");
system("pause");
}
}
 
/* Модуль отображения полученного файла */
 
void 
visualizza (FILE *beta)
{
Alberghi albergo1;
int stato;
int i=1;
 
beta=fopen(outputfName,"rb");
stato=fread(&albergo1,sizeof(Alberghi),1,beta);
 
    while (stato==1){ 
        printf("\n[%d] %s %s %d %.2f %d %.2f", i, albergo1.city, albergo1.hotelName, albergo1.room1, albergo1.room1Cost, albergo1.room2, albergo1.room2Cost);
                i++;
        fread(&albergo1,sizeof(albergo1),1,beta);
        stato=fread(&albergo1,sizeof(Alberghi),1,beta);
        }
        
fclose(beta);
 
printf("\n\n");
system("pause");
}
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
15.12.2012, 03:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Запись и чтение бинарного файла (C (СИ)):

Запись/чтение бинарного файла - C (СИ)
У меня есть процедура которая на вход принимает строку , имя файла , и записывает новый элемент в формате &lt;имя&gt; &lt;инициалы&gt; &lt;пол &gt; &lt;группа&gt;...

Чтение бинарного файла - C (СИ)
Как считать файл с помошью fread - в файле первые 4 байта вот такие 00 00 00 08 делаю так int byteCount; fread(&amp;byteCount,...

Чтение строки из бинарного файла - C (СИ)
вопрос в шапке: как считать строку из бинарного файла? размер строки не известен... про азы типа fopen рассказывать не надо... з.ы....

Считывание и запись бинарного файла - C (СИ)
файл считывается, записывается в массив. Затем создается новый файл, в него записываются данные из массива. Содержимое исходного...

Чтение бинарного файла на втором проходе цикла завершается с ошибкой - C (СИ)
Добрый день,подскажите как решить проблемку. Читаю бинарный файл в который через некоторое время добавляются новые данные весом 20 КБ.И вот...

Запись структуры в конец бинарного файла - C (СИ)
Доброго времени суток! Нужно записать в конец бинарного файла структуру. struct realtor{ int id; char surname; char name; ...

12
polyaKIDze
63 / 63 / 12
Регистрация: 16.07.2012
Сообщений: 147
15.12.2012, 04:27 #2
Цитата Сообщение от leon91 Посмотреть сообщение
FILE *alfa, *beta;
C
1
FILE *alfa, beta;
0
leon91
1 / 1 / 0
Регистрация: 15.12.2012
Сообщений: 6
15.12.2012, 04:31  [ТС] #3
Цитата Сообщение от polyaKIDze Посмотреть сообщение
C
1
FILE *alfa, beta;
В смысле???
0
polyaKIDze
63 / 63 / 12
Регистрация: 16.07.2012
Сообщений: 147
15.12.2012, 04:41 #4
FILE * - это тип переменной. Я завел две переменные такого типа. А у вас я не понял, что происходит.
0
leon91
1 / 1 / 0
Регистрация: 15.12.2012
Сообщений: 6
15.12.2012, 04:47  [ТС] #5
polyaKIDze, Вы таким образом убрали указатель на файл beta, а не завели две переменные.

FILE *alfa, *beta; равнозначно FILE *alfa; FILE *beta;

Вот такое объявление переменных правильно. А Вы запутались по-моему.
0
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
15.12.2012, 06:52 #6
******
0
Байт
Эксперт C
16553 / 10823 / 1640
Регистрация: 24.12.2010
Сообщений: 20,898
15.12.2012, 09:57 #7
Цитата Сообщение от leon91 Посмотреть сообщение
Проблема возникает при попытке чтения из файла.
Какого рода проблема?
На первый взгляд. Непонятно, зачем ты читаешь 2 раза в строчках 78-79.
Строчку 76 разбей на меньшие (просто переносом на другую строку по запятым), а то ее невозможно анализировать, а возможно ошибка кроется там.
Ну и еще не очень понятно, зачем ты в функции передаешь указатели на неоткрытые файлы. Т.е. это не ошибка, но действие бессмысленное.
ЗЫ. Замечания твоего оппонента в постах #2, #4 можешь без ущерба для здоровья пропустить мимо ушей.
0
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
15.12.2012, 10:45 #8
Так у вас корректная программа. Вы хорошо справились с задачей. Вы ищете ошибку, а у вас нету ошибок.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
#define inputfName "input.txt"
#define outputfName "output.txt"
 
typedef struct
{
    char city[40]; // citta'     //40
    char hotelName[40]; // nome di albergo  //40
    int room1; // numero di stanze singole   //4
    int room2; // numero di stanze doppie    // 4
    float room1Cost; // costo di una stanza singola // 4
    float room2Cost; // costo di una stanza doppia  // 4
} Alberghi;
 
 
void parsingToStruct (FILE *alfa, FILE *beta);
void visualizza (FILE *beta);
 
 
int
main()
{
FILE *alfa, *beta;
 
parsingToStruct (alfa, beta);
visualizza (beta);
}
 
/* Модуль парсинга и создания бинарного файла */
 
void
parsingToStruct (FILE *alfa, FILE *beta)
{
Alberghi albergo1;
int n=0;
 
alfa=fopen(inputfName,"r");
beta=fopen(outputfName, "wb");
 
if(alfa==NULL)
printf("Errore");
else {
rewind(alfa);
while( fscanf(alfa,"%[^;]; %[^;]; %d; %f; %d; %f;\n",albergo1.city, albergo1.hotelName, &albergo1.room1, &albergo1.room1Cost, &albergo1.room2, &albergo1.room2Cost) != EOF){
for(int i = strlen(albergo1.city); i<40;i++)
albergo1.city[i]='\0';
for(int i = strlen(albergo1.hotelName); i<40;i++)
albergo1.hotelName[i]='\0';
fwrite(&albergo1, sizeof(Alberghi), 1, beta);
printf("\n[%d] %s %s %d %.2f %d %.2f",  n,  albergo1.city, albergo1.hotelName, albergo1.room1, albergo1.room1Cost, albergo1.room2, albergo1.room2Cost);
n++;
}
fclose(alfa);
fclose(beta);
 
printf("\n\n");
system("pause");
}
}
 
/* Модуль отображения полученного файла */
 
void
visualizza (FILE *beta)
{
Alberghi albergo1;
int stato;
int i=1;
beta=fopen(outputfName,"rb");
stato=fread(&albergo1, sizeof(Alberghi), 1, beta);
while (stato==1){
printf("\n[%d] %s %s %d %.2f %d %.2f", i, albergo1.city, albergo1.hotelName, albergo1.room1, albergo1.room1Cost, albergo1.room2, albergo1.room2Cost);
i++;
fread(&albergo1,sizeof(albergo1), 1, beta);
stato=fread(&albergo1, sizeof(Alberghi), 1, beta);
}
fclose(beta);
printf("\n\n");
system("pause");
}
Добавлено через 8 минут
Объясняю, почему в вашей программе нет ошибок. Вы создали структуру Alberghi. Давайте посмотрим, какой размер этой структуры. Размер типа char - 1 байт. Таким образом char city[40]; это 40 байт. Таким образом char hotelName[40]; еще 40 байт. Размер типа int - 4 байта.
Таким образом, int room1 это 4 байта int room2 еще 4 байта Размер типа float - 4 байта. Таким образом float room1Cost это 4 байта, float room2Cost 4 байта

Таким образом суммарный размер структуры - 96. При двоичной записи ВЫ ЗАПИСЫВАЕТЕ 96 БАЙТ !!!!!!!!!!!!!!!!!!!!!!!! Обратите особе внимание - именно 96 байт и никак иначе.

Однако у вас есть маленькая неточность - появляется мусор в структуре.
Для того чтобы мусора не было нужно сделать ZeroMemory для полей структуры Alberghi которые представляют из себя массив char.

Что значит fscanf(alfa,"%[^;]; %[^;]; я и сам не понял, но оно является правильным.

Комментатор #2 и #4 ошибся.

Добавлено через 5 минут
C
1
2
fread(&albergo1,sizeof(albergo1), 1, beta);
stato=fread(&albergo1, sizeof(Alberghi), 1, beta);
Первый fread является лишним.
1
leon91
1 / 1 / 0
Регистрация: 15.12.2012
Сообщений: 6
15.12.2012, 15:46  [ТС] #9
Цитата Сообщение от Байт Посмотреть сообщение
На первый взгляд. Непонятно, зачем ты читаешь 2 раза в строчках 78-79.
Цитата Сообщение от asidorchenko Посмотреть сообщение
C
1
2
fread(&albergo1,sizeof(albergo1), 1, beta);
stato=fread(&albergo1, sizeof(Alberghi), 1, beta);
Первый fread является лишним.
Вы правы, ошибся .

Цитата Сообщение от Байт Посмотреть сообщение
Какого рода проблема?


Как подметил asidorchenko:

Цитата Сообщение от asidorchenko Посмотреть сообщение
появляется мусор в структуре.
Для того чтобы мусора не было нужно сделать ZeroMemory для полей структуры Alberghi которые представляют из себя массив char.
ZeroMemory это макрос только под Windows. Я так понимаю, что должен использовать memset, но я точно не понимаю, как это сделать. Вот такая инициализация вначале цикла while приводит к ошибке сегментации после парсинга первой строчки из файла:

C
1
2
memset(&albergo1.city, '\0', sizeof(Alberghi) );
memset(&albergo1.hotelName, '\0', sizeof(Alberghi) );
Цитата Сообщение от asidorchenko Посмотреть сообщение
Что значит fscanf(alfa,"%[^;]; %[^;]; я и сам не понял, но оно является правильным.
По сути парсит файл, останавливаясь на ; . Т.к. поле albergo1.city и albergo1.hotelName может содержать пробелы, то использовать char как тип переменной мы не можем. %[^;] устанавливает тип string (как я понимаю). Нашел данное решение в интернете и оно мне показалось более разумным, чем создавать отдельный массив под переменную и делать цикл проверки каждого символа пока не наткнемся на ; ...
0
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
15.12.2012, 17:28 #10
C
1
2
memset(&albergo1.city, '\0', 40);
memset(&albergo1.hotelName, '\0', 40);
1
Миниатюры
Запись и чтение бинарного файла   Запись и чтение бинарного файла  
leon91
1 / 1 / 0
Регистрация: 15.12.2012
Сообщений: 6
15.12.2012, 17:45  [ТС] #11
asidorchenko, спасибо огромное!!!

Ошибка была еще более банальная, чем memset!!! Неправильная запись fwrite!!!

C
1
fwrite(&albergo1, sizeof(Alberghi), n, beta);
Программа работает даже без memset! Если упустить его, будет ли что-то???
0
asidorchenko
379 / 205 / 25
Регистрация: 09.04.2012
Сообщений: 635
16.12.2012, 06:09 #12
Цитата Сообщение от leon91 Посмотреть сообщение
asidorchenko, спасибо огромное!!!

Ошибка была еще более банальная, чем memset!!! Неправильная запись fwrite!!!

C
1
fwrite(&albergo1, sizeof(Alberghi), n, beta);
Программа работает даже без memset! Если упустить его, будет ли что-то???
У вас мусор в структуре, поэтому нужно делать memset.
0
leon91
1 / 1 / 0
Регистрация: 15.12.2012
Сообщений: 6
16.12.2012, 06:12  [ТС] #13
Цитата Сообщение от asidorchenko Посмотреть сообщение
У вас мусор в структуре, поэтому нужно делать memset.
В том то и дело, что после исправлений программа одинаково отлично работает что с memset, что без него. Протестировал на файле большего размера, мусора больше не наблюдалось.
0
16.12.2012, 06:12
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.12.2012, 06:12
Привет! Вот еще темы с ответами:

Запись и чтение из файла - C (СИ)
Наверное глупый вопрос, но пожалуйста, подскажите как правильно считывать из файла, если в файле хранятся значения разных переменных и...

Запись/чтение из файла - C (СИ)
#include &lt;stdio.h&gt; main() { char product_name; int product_mass; int product_price; ...

Запись/чтение из txt файла. - C (СИ)
Реализую запись в файл/чтение из файла, имя которого задается с клавиатуры: FILE *aa int a1; printf(&quot;Файл-источник:\n&quot;); ...

Чтение из файла и запись в файл - C (СИ)
скажите пож-та если у меня например есть текстовый файл и в нем записаны ФИО студентов ,оценки из пяти символов у каждого ,номер...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru