Форум программистов, компьютерный форум, киберфорум
Visual C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.79/14: Рейтинг темы: голосов - 14, средняя оценка - 4.79
анимешник++
 Аватар для Iworb
95 / 62 / 7
Регистрация: 03.11.2009
Сообщений: 427

Чтение структуры из файла

02.03.2011, 18:18. Показов 2888. Ответов 4

Студворк — интернет-сервис помощи студентам
Ранее с файлами в WinApi не работал, поэтому собственно и возник такой вопрос: файл я кое-как открыл (у меня есть его хэндл - FileHandle и его размер - FileSize).
В файле структура типа:
Daevo 18695540 169.2 1999
BMW 55662233 145.3 2008
Ford 12599336 325.9 2004
Lada 01549856 984.21 1992
Lada 01549426 365.47 1998
Lada 08649856 448.33 1999
Toyota 86533217 894.3 2004
Crysler 15239850 182.12 2008
Марка_машины ид_машины(не более 8 цифр) пробег год_выпуска

Соответственно я не знаю заранее размер каждого поля.
Есть класс, в который заносятся все эти данные.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Work
{
    public:
        Work() {list.clear(); processing=-1;}
        Work(MACHINE_INFO in, int num=1)
        {
            list.clear();
            for(int i=0;i<num;i++) list.push_back(in);
            processing=list.size()-1;
        }
        ~Work() {list.clear();}
        MACHINE_INFO& operator[](int i)
        {
            if(i<0&&list.size()>0) return list[0];
            if(i>list.size()&&list.size()>0) return list[list.size()-1];
            if(list.size()>0) return list[i];
        }
        bool read();
        std::vector<MACHINE_INFO> list;
        int processing;
};
Тут нас интересует только вектор, в который будут заноситься значения.
И есть структура:
C++
1
2
3
4
5
6
7
typedef struct _MACHINE_INFO
{
    char Mark[255];
    char SerialNumber[9];
    float Mileage;
    int Year;
}MACHINE_INFO;
Надо, собственно Work::read описать. Пока написал не много, просто ума не приложу как считывать строки и пр. с файла:
C++
1
2
3
4
5
6
7
8
9
    bool Work::read()
    {
        TCHAR *buf=new TCHAR[FileSize];
        DWORD num;
        TCHAR fn[55];
        ReadFile(FileHandle,buf,1000,&num,NULL);
        delete []buf;
        return true;
    }
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
02.03.2011, 18:18
Ответы с готовыми решениями:

Чтение структуры из файла
Нужно считать структуру из файла .def но по итогу выводит: cþÞD:\Topolog_6329\PDMC\VT5491_PDMC_4\VT5491N_6IN_m_4_150.t29 61138 0 ...

Чтение структуры из файла
(программа на С) В общем, задача написать программу, которая из файла вида: будет заносить данные в структуру (фио, год рождения,...

Чтение структуры из файла
Всем привет! читаю файл через бинарный режим содержимое файла(HEX) : 50 49 43 40 50 23 00 4A 50 47 00 00 FF D8 FF E0 00 10 ...

4
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
03.03.2011, 13:24
ReadFile не читает по строкам.
Если читать по строкам, то fgets. Ну и, соответсвенно, fopen. Или преобразовать HANDLE в FILE (но такое решение не совсем гуд).

Добавлено через 18 минут
А так
C++
1
2
3
4
5
6
do
{
    result = ReadFile(FileHandle,buf,1000,&num,NULL);
    Work::Parse(buf);
}
while (result && num);
Где, Parse - реализованный вами метод вашего класса Work, скорее всего закрытый, в котором вы разбираете, преобразовываете и сохраняете считанные данные.
Т.к. длина строки не фиксированная, но вы уверенны, что размер буфера в любом случае перекроет длину строки, то в общем случае при чтении в буфер может попасть часть следующей строки. На этот случай нужно предусмотреть какой-то механизм.
0
анимешник++
 Аватар для Iworb
95 / 62 / 7
Регистрация: 03.11.2009
Сообщений: 427
03.03.2011, 18:48  [ТС]
Цитата Сообщение от bigredcat Посмотреть сообщение
ReadFile не читает по строкам.
Если читать по строкам, то fgets. Ну и, соответсвенно, fopen. Или преобразовать HANDLE в FILE (но такое решение не совсем гуд).

Добавлено через 18 минут
А так
C++
1
2
3
4
5
6
do
{
    result = ReadFile(FileHandle,buf,1000,&num,NULL);
    Work::Parse(buf);
}
while (result && num);
Где, Parse - реализованный вами метод вашего класса Work, скорее всего закрытый, в котором вы разбираете, преобразовываете и сохраняете считанные данные.
Т.к. длина строки не фиксированная, но вы уверенны, что размер буфера в любом случае перекроет длину строки, то в общем случае при чтении в буфер может попасть часть следующей строки. На этот случай нужно предусмотреть какой-то механизм.
Вот этот Parse мне и нужно реализовать. Мне нужно считать данные и преобразовать их в структуру, вроде четко сформулировал цель...
0
375 / 322 / 32
Регистрация: 24.02.2011
Сообщений: 1,512
Записей в блоге: 1
04.03.2011, 11:23
Цитата Сообщение от Iworb Посмотреть сообщение
Вот этот Parse мне и нужно реализовать. Мне нужно считать данные и преобразовать их в структуру, вроде четко сформулировал цель...
Ну вот пример. На скорячок написал, собственно, приближенный алгоритм.
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
int main()
{
    using namespace std;
 
    HANDLE fileHandle = INVALID_HANDLE_VALUE;
    fileHandle = CreateFileA("db.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL);
 
    DWORD fileSize = GetFileSize(fileHandle, NULL);
 
    // Выделяем буфер по размеру файла
    char* buffer = new char[fileSize];
 
    DWORD bytesRead = 0;
    // Читаем сразу весь файл.
    ReadFile(fileHandle, buffer, fileSize, &bytesRead, NULL);
 
    MACHINE_INFO mi = {0}; // Mark[254] = '\0', SerialNumber[8] = '\0'
    char miles[9] = {0}; // пробег в 9999999 миль более чем достаточное ограничение
    char year[5] = {0};
 
    // Парсим буфер.
    for (DWORD i = 0; i < fileSize; i++)
    {
        // Пропускаем эти символы
        if ((buffer[i] == '\n') || (buffer[i] == '\r')) i++;
        else
        {
            // Марка
            for (DWORD j = 0; j < 254 && i < fileSize; j++, i++)
            {
                if (buffer[i] == ' ') {mi.Mark[j] = '\0'; break; }
                else mi.Mark[j] = buffer[i];
            }
            i++; // следующий символ.
            // Идентификатор
            for (DWORD j = 0; j < 8 && i < fileSize; j++, i++)
            {
                if (buffer[i] == ' ') {mi.SerialNumber[j] = '\0'; break;}
                else mi.SerialNumber[j] = buffer[i];
            }
            i++; // следующий символ.
            // Пробег
            for (DWORD j = 0; j < 8 && i < fileSize; j++, i++)
            {
                if (buffer[i] == ' ') {miles[j] = '\0'; break;}
                else miles[j] = buffer[i];
            }
            mi.Mileage = (float)atof(miles);
            i++; // следующий символ.
            // Год выпуска
            for (DWORD j = 0; j < 4 && i < fileSize; j++, i++)
            {
                if (buffer[i] == ' ') {year[j] = '\0'; break;}
                else year[j] = buffer[i];
            }
            mi.Year = atoi(year);
 
            // Здесь нужно добавить запись в список, а мы просто выводим то, что есть
            cout << mi.SerialNumber << " " << mi.Mark << " " << mi.Year << " " << mi.Mileage << endl;
        }
    }
 
    delete[] buffer;
    CloseHandle(fileHandle);
 
    system("PAUSE");
    return 0;
}
Но все это скорее для игрушечных целей.
А если ваша база данных будет сотни мегабайт, а если гигабайт? Тут нужен другой подход
2
анимешник++
 Аватар для Iworb
95 / 62 / 7
Регистрация: 03.11.2009
Сообщений: 427
07.03.2011, 16:50  [ТС]
Спасибо огромное, но начиная со второй записи не считывается первая буква в имени марки, сейчас исправлять буду.

Добавлено через 1 минуту
UPD: всё, там просто в цикле внешнем нужно было убрать инкремент i
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
07.03.2011, 16:50
Помогаю со студенческими работами здесь

Чтение структуры с файла
Имеется следующая структура: struct car { int id; char brand; char model; int yearOfRelease; char color; ...

Чтение структуры из файла
Из файла выводит все прекрасно, так как надо, но в конце, не понимаю почему, выводит последнюю структуру два раза В чем проблема,...

Чтение структуры из файла
Добрый вечер. Помогите пожалуйста застрял на одном месте: 1. Используя ввод-вывод в стиле С++ создать файл и записать в него...

Чтение структуры из файла
Добрый день. Пытаюсь считать структуру из файла в структуру(идентичную структуре файла) получается такой код: #include...

Чтение структуры из файла
мне надо считать структуру из файла и вывести данные на экран. считывать-то считывает.. но вот выводит ерунду какую-то. помогите...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Новые блоги и статьи
модель ЗдравоСохранения 8. Подготовка к разному выполнению заданий
anaschu 08.04.2026
https:/ / github. com/ shumilovas/ med2. git main ветка * содержимое блока дэлэй из старой модели теперь внутри зайца новой модели 8ATzM_2aurI
Блокировка документа от изменений, если он открыт у другого пользователя
Maks 08.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа, разработанного в конфигурации КА2. Задача: запретить редактирование документа, если он открыт у другого пользователя. / / . . .
Система безопасности+живучести для сервера-слоя интернета (сети). Двойная привязка.
Hrethgir 08.04.2026
Далее были размышления о системе безопасности. Сообщения с наклонным текстом - мои. А как нам будет можно проверить, что ссылка наша, а не подделана хулиганами, которая выбросит на другую ветку и. . .
Модель ЗдрввоСохранения 7: больше работников, больше ресурсов.
anaschu 08.04.2026
работников и заданий может быть сколько угодно, но настроено всё так, что используется пока что только 20% kYBz3eJf3jQ
Дальние перспективы сервера - слоя сети с космологическим дизайном интефейса карты и логики.
Hrethgir 07.04.2026
Дальнейшее ближайшее планирование вывело к размышлениям над дальними перспективами. И вот тут может быть даже будут нужны оценки специалистов, так как в дальних перспективах всё может очень сильно. . .
Горе от ума
kumehtar 07.04.2026
Эта мне ментальная установка, что вот прямо сейчас, мол, мне для полного счастья не хватает (нужное вписать), и когда я этого достигну - тогда и полный кайф. Одна из самых сильных ловушек на пути. . . .
Использование значений реквизитов справочника в документе, с определенными условиями и правами
Maks 07.04.2026
1. Контроль срока действия договора Алгоритм из решения ниже реализован на примере нетипового документа "ЗаявкаНаРаботу", разработанного в конфигурации КА2. Задача: уведомлять пользователя, если. . .
Доступность команды формы по условию
Maks 07.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "СписаниеМатериалов", разработанного в конфигурации КА2. Задача: сделать доступной кнопку (команда формы "ЗавершитьСписание") при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru