Форум программистов, компьютерный форум, киберфорум
Наши страницы
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
sanchezsanya
9 / 9 / 6
Регистрация: 16.10.2013
Сообщений: 72
1

Заполнение массива структур из файла

02.03.2014, 17:55. Просмотров 951. Ответов 12
Метки нет (Все метки)

Файл имеет вид:
Код
1 Sidorov Moscow 3 4
2 Petrov St.Peterburg 5 31
3 Falin Chetai 24 32
4 Sokolov Ufa 32 34
5 Demyanov Moscow 4 6
Структура имеет вид:
C
1
2
3
4
5
6
7
struct DATA {
    char number[30];
    char name[30];
    char team[15];
    int point1;
    int point2;
};
Вот кусок программы, который отвечает за заполнение массива:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
        struct DATA *tek;
    int *a,n=0,i;
    char p[2*KOLNAME+2*KOLTEAM];
    rewind(file);
    while (fgets((char *)&p,sizeof(struct DATA),file))
        n++;
    
    tek=(struct DATA*)malloc(n*sizeof(struct DATA));
    if (tek==NULL){
        puts ("Ошибка распределения памяти");
        getch();
        return ;
    }
    for (i=0;i<n;i++)
        fscanf (file,"%s %s %s %d %d",&tek[i].number,&tek[i].name,&tek[i].team,&tek[i].point1,&tek[i].point2);
Я считаю, что ошибка где-то тут:
for (i=0;i<n;i++)
fscanf (file,"%s %s %s %d %d",&tek[i].number,&tek[i].name,&tek[i].team,&tek[i].point1,&tek[i].point2);

Ошибка заключается в неправильном заполнении массива структуры.
например, если вызывать printf ("%s",tek[0].name) выводятся буквы МММММ и с каждым запуском программы их становится в 2 раза больше чем было и так далее, не пойму в чем дело
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.03.2014, 17:55
Ответы с готовыми решениями:

Заполнение массива структур
Вот мой днищенский код одной из функций: void redakt(struct zavod zapis){ FILE *bd; ...

Заполнение массива структур
При заполнении структуры в цикле все указатели (с 0 - 4 елемент ) в массиве структур принимают...

Заполнение таблицы(массива структур)
Имеется файл такого содержания: root : qwerty: 123 : 465 : Acc. for root : /root : /bin/sh...

Заполнение массива структур - при вводе более двух элементов возникает ошибка
Задача: создать массив структур и заполнить с клавиатуры (произвольной длины). Подскажите...

Чтение массива структур из файла
Здравствуйте, помогите решить проблемку. Имеется функция чтения: int Read(MPh Pdata, int len) {...

12
zss
Модератор
Эксперт С++
7917 / 7108 / 4443
Регистрация: 18.12.2011
Сообщений: 18,775
Завершенные тесты: 1
02.03.2014, 18:20 2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
struct DATA *tek;
    int *a,n=0,i;
    char p[2*KOLNAME+2*KOLTEAM];
    rewind(file);
    while (fgets((char *)&p,sizeof(struct DATA),file))
        n++;
     rewind(file); // файл снова надо перемотать
    tek=(struct DATA*)malloc(n*sizeof(struct DATA));
    if (tek==NULL){
        puts ("Ошибка распределения памяти");
        getch();
        return ;
    }
    for (i=0;i<n;i++)
        fscanf (file,"%s %s %s %d %d",tek[i].number,tek[i].name,tek[i].team,// для строк & не надо
               &tek[i].point1,&tek[i].point2);
0
sanchezsanya
9 / 9 / 6
Регистрация: 16.10.2013
Сообщений: 72
02.03.2014, 19:04  [ТС] 3
Убрал амперсенты у строк, ничего не изменилось, так же прога не работает
0
zss
Модератор
Эксперт С++
7917 / 7108 / 4443
Регистрация: 18.12.2011
Сообщений: 18,775
Завершенные тесты: 1
02.03.2014, 19:22 4
А файл перемотали?
1
sanchezsanya
9 / 9 / 6
Регистрация: 16.10.2013
Сообщений: 72
02.03.2014, 19:25  [ТС] 5
rewind(file);
вот эта функция обновляет чтение с файла
0
zss
Модератор
Эксперт С++
7917 / 7108 / 4443
Регистрация: 18.12.2011
Сообщений: 18,775
Завершенные тесты: 1
02.03.2014, 19:27 6
и еще поправьте
C++
1
2
fscanf(file,"%s%s%s%d%d",tek[i].number,tek[i].name,tek[i].team,
            &tek[i].point1,&tek[i].point2);
1
sanchezsanya
9 / 9 / 6
Регистрация: 16.10.2013
Сообщений: 72
02.03.2014, 20:30  [ТС] 7
Ничего не понимаю. Сейчас ничего не трогал, и вообще перестала работать вся программа, вернее все 3 пункта, которые были отлажены и работали без сбоев.Все 3 функции которые работали, сейчас при обращении к каждой выдает ошибку:
Необработанное исключение по адресу 0xCDCDCDCD в ConsoleApplication11.exe: 0xC0000005: нарушение прав доступа при исполнении по адресу 0xCDCDCDCD.

Добавлено через 46 минут
Так, с распределением памяти я вопрос решил, теперь опять стоит вопрос о вводе данных с файла в массив структур, ни
C++
1
2
fscanf (file,"%s %s %s %d %d",tek[i].number,tek[i].name,tek[i].team,// для строк & не надо
               &tek[i].point1,&tek[i].point2);
ни

C++
1
2
fscanf(file,"%s%s%s%d%d",tek[i].number,tek[i].name,tek[i].team,
            &tek[i].point1,&tek[i].point2);
не помогают, все точно так же
0
Arcor
5074 / 1946 / 413
Регистрация: 20.11.2009
Сообщений: 6,401
Записей в блоге: 1
02.03.2014, 21:21 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
#include <stdlib.h>
#include <stdio.h>
// объявляем структуру
typedef struct  {
    char number[30];
    char name[30];
    char team[15];
    int point1;
    int point2;
}DATA;
 
int main(int argc, char *argv[])
{
    DATA *tec = NULL; // массив структур
    int i = 0;        // для счета
    int len;          // длина, сколько записей в файле
    FILE *f = NULL;   // для файла
    f = fopen("D:\\11.txt", "r"); // открываем для чтения
    // проверяем на наличие файла
    if (f == NULL) 
    {
        printf("Error!!! File not found\n\n");
        getchar();
        return;
    }
 
    // начинаем чтение пока не закончится файл
    while (!feof(f))
    {
        if(!feof(f))
        {   
            // нашли новую запись в файле? увеличиваем память и записываем в структуру прочитанное
            tec = (DATA*)realloc(tec, sizeof(DATA) * (i + 1));  
                if (tec == NULL) 
                {
                    printf("Error!!! Cannot allocate more memory.\n\n");
                    getchar();
                    return;
                }
            fscanf(f, "%s%s%s%d%d", tec[i].number, tec[i].name, tec[i].team, &tec[i].point1, &tec[i].point1);
            i++;
        }
    }
 
    len = i;
    // ну и выведем на экран все что считали из файла
    for (i = 0; i < len; i++)
        printf("%s %s %s %d %d\n",tec[i].number, tec[i].name, tec[i].team, tec[i].point1, tec[i].point1);
    // и закрываем файл
    fclose(f);
    system("pause");
    return 0;   
}
сильно не ругайтесь, если, что не так, я тоже недавно только начал въезжать в Си
1
Миниатюры
Заполнение массива структур из файла  
zss
Модератор
Эксперт С++
7917 / 7108 / 4443
Регистрация: 18.12.2011
Сообщений: 18,775
Завершенные тесты: 1
02.03.2014, 21:24 9
А чем Вам не понравился исходный метод выделения памяти
C++
1
2
3
4
while (fgets((char *)&p,sizeof(struct DATA),file))
        n++;
     rewind(file); // файл снова надо перемотать
    tek=(struct DATA*)malloc(n*sizeof(struct DATA));
А сейчас у Вас сразу realloc без начального malloc.
Не думаю, что все компиляторы это понимают
1
Arcor
5074 / 1946 / 413
Регистрация: 20.11.2009
Сообщений: 6,401
Записей в блоге: 1
02.03.2014, 21:37 10
Цитата Сообщение от zss Посмотреть сообщение
А чем Вам не понравился исходный метод выделения памяти
2 раза читать файл, первый раз, чтобы посмотреть его длину, второй раз чтобы прочитать из него, зачем так делать? если я не прав прошу переубедить
Цитата Сообщение от zss Посмотреть сообщение
Не думаю, что все компиляторы это понимают
писал в MSVS 2010, проверил в Pelles и в Dev-С++ результат везде одинаковый

Цитата Сообщение от zss Посмотреть сообщение
А сейчас у Вас сразу realloc без начального malloc.
так я переменной сразу дал значение NULL, обнулил память, а затем по мере необходимости добавлял
0
zss
Модератор
Эксперт С++
7917 / 7108 / 4443
Регистрация: 18.12.2011
Сообщений: 18,775
Завершенные тесты: 1
02.03.2014, 21:40 11
Цитата Сообщение от Arcor Посмотреть сообщение
так я переменной сразу дал значение NULL, обнулил память, а затем по мере необходимости добавлял
А кто Вам сказал, что так можно.
Если указатель нулевой, то как его можно перераспределить?
Лишний раз прочитать маленький файл совсем не напряжно, т.к. операции буферизованы,
поэтому чтение все равно идет из памяти.
0
sanchezsanya
9 / 9 / 6
Регистрация: 16.10.2013
Сообщений: 72
02.03.2014, 21:41  [ТС] 12
Спасибо огроменное!!!! Ошибка была в том, что я забыл перемотать файл (rewind(file)) после того, как прокрутил его для подсчета количества строк!!!
0
Arcor
5074 / 1946 / 413
Регистрация: 20.11.2009
Сообщений: 6,401
Записей в блоге: 1
02.03.2014, 21:49 13
блин, вот тут исправить надо последний аргумент там point1 стояло, а надо point2
fscanf(f, "%s%s%s%d%d", tec[i].number, tec[i].name, tec[i].team, &tec[i].point1, &tec[i].point2);

и вот тут fscanf(f, "%s%s%s%d%d", tec[i].number, tec[i].name, tec[i].team, &tec[i].point1, &tec[i].point2);

Добавлено через 6 минут
Цитата Сообщение от zss Посмотреть сообщение
А кто Вам сказал, что так можно.
Если указатель нулевой, то как его можно перераспределить?
C
1
void * realloc( void * ptrmem, size_t size );
Функция realloc выполняет перераспределение блоков памяти.
Размер блока памяти, на который ссылается параметр ptrmem изменяется на size байтов. Блок памяти может уменьшаться или увеличиваться в размере.

Эта функция может перемещать блок памяти на новое место, в этом случае функция возвращает указатель на новое место в памяти. Содержание блока памяти сохраняется даже если новый блок имеет меньший размер, чем старый. Отбрасываются только те данные, которые не вместились в новый блок. Если новое значение size больше старого, то содержимое вновь выделенной памяти будет неопределенным.

В случае, если ptrmem равен NULL, функция ведет себя именно так, как функция malloc, т. е. выделяет память и возвращает указатель на этот участок памяти.

В случае, если size равен 0, ранее выделенная память будет освобождена, как если бы была вызвана функция free, и возвращается нулевой указатель.
---------------------------------------
интересно, то, что красным написано
0
02.03.2014, 21:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.03.2014, 21:49

Чтение массива структур из файла
читаю по while !feof(), проблема в том, что если файл пустой, то все равно проскакивает на одну...

Чтение массива структур из текстового файла
Задание таково: есть структура из 2-х полей:№телефона и комментарий Создать тел.книгу. ...

Выполнить считывание и заполнение массива строк из заданного текстового файла
Реализовать работу с массивом строк: a. Выполнить считывание и заполнение массива строк из...


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

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

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