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

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

02.03.2011, 18:18. Показов 2874. Ответов 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
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): Обработчик клика мыши в браузере ПК и касания экрана в браузере на мобильном устройстве
8Observer8 02.02.2026
Содержание блога Для начала пошагово создадим рабочий пример для подготовки к экспериментам в браузере ПК и в браузере мобильного устройства. Потом напишем обработчик клика мыши и обработчик. . .
Философия технологии
iceja 01.02.2026
На мой взгляд у человека в технических проектах остается роль генерального директора. Все остальное нейронки делают уже лучше человека. Они не могут нести предпринимательские риски, не могут. . .
SDL3 для Web (WebAssembly): Вывод текста со шрифтом TTF с помощью SDL3_ttf
8Observer8 01.02.2026
Содержание блога В этой пошаговой инструкции создадим с нуля веб-приложение, которое выводит текст в окне браузера. Запустим на Android на локальном сервере. Загрузим Release на бесплатный. . .
SDL3 для Web (WebAssembly): Сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
SDL3 для Web (WebAssembly): Установка Emscripten SDK (emsdk) и CMake для сборки C и C++ приложений в Wasm
8Observer8 30.01.2026
Содержание блога Для того чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. . . .
SDL3 для Android: Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
SDL3 для Android: Загрузка PNG с альфа-каналом с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru