Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.57/7: Рейтинг темы: голосов - 7, средняя оценка - 4.57
9 / 9 / 2
Регистрация: 02.11.2012
Сообщений: 153

Чтение/запись файла

20.02.2013, 03:49. Показов 1519. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Вот сделал такую прогу. Очень простая. Создает файл, где есть 100 полей.
Каждое поле это строка из индекса, названия, кол-ва (например тут инструментов), цены.
например
5 Молоток 10 50.50
И реализовал простенькие методы для работы.
Но почему-то не работает 5 метод. Когда я создаю два объекта
1 молоток 2 4
2 тяпка 6 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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Инвентаризация.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include <fstream>
#include <iostream>
using namespace std;
 
struct Instrument {
    int num;
    char instName[30];
    int kolvo;
    double price;
};
 
int getChoice();
int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "Russian");
    fstream myFileReader("hardware.dat", ios::in | ios::out);
 
    if (! myFileReader) {
        cerr << "Файл не может быть открыт" << endl;
        system("pause");
        exit(1);
    }
 
    Instrument my = {0, "", 0, 0.0};
 
    for (int i = 0; i < 100; i++) {
        myFileReader.write((char *) &my, sizeof(Instrument));
    }
    myFileReader.flush();
    int choice;
    while ((choice = getChoice()) != 7) {
        switch(choice) {
            //вставляет новый инструмент
        case(1):
            {
                cout << "Введите индекс, название, кол-во, цену. " << endl;
                cin >> my.num >> my.instName >> my.kolvo >> my.price;
                myFileReader.seekg((my.num - 1) * sizeof(Instrument));
                Instrument temp;
                myFileReader.read((char *) &temp, sizeof(Instrument));
                if (temp.num == 0) {
                    myFileReader.seekp((my.num - 1) * sizeof(Instrument));
                    myFileReader.write((char *) &my, sizeof(Instrument));
                    myFileReader.flush();
                }
                else
                    cout << "Данный счёт уже существует!" << endl;
                break;
            }
            //печатает уже введенные инструменты
        case(2):
            {
                cout << "Полный список: " << endl;
                myFileReader.seekg(0);
                myFileReader.read((char *) &my, sizeof(Instrument));
                while (! myFileReader.eof()) {
                    if (my.num != 0) {
                        cout << my.num << ' ' << my.instName << ' ' << my.kolvo << ' ' << my.price << endl;
                    }
                    myFileReader.read((char *) &my, sizeof(Instrument));
                }
                break;
            }
            //удаляет инструмент
        case(3):
            {
                cout << "Введите номер записи, которую вы хотите удалить: " << endl;
                int num;
                cin >> num;
                myFileReader.seekp((num - 1) * sizeof(Instrument));
                Instrument temp = {0, "", 0, 0.0};
                myFileReader.write((char *) &temp, sizeof(Instrument));
                myFileReader.flush();
                break;
            }
            //изменяет имя инструмента
        case(4):
            {
                cout << "Введите номер записи, в которой вы хотите сделать изменение: " << endl;
                int num;
                cin >> num;
                myFileReader.seekg((num - 1) * sizeof(Instrument));
                myFileReader.read((char *) &my, sizeof(Instrument));
                if (my.num == 0) {
                    cout << "Такой записи не существует" << endl;
                    break;
                }
                cout << "Введите новое название: ";
                cin >> my.instName;
                myFileReader.seekp((num - 1) * sizeof(Instrument));
                myFileReader.write((char *) &my, sizeof(Instrument));
                myFileReader.flush();
                break;
            }
            //изменяет кол-во инструментов
        case(5):
            {
                cout << "Введите номер записи, в которой вы хотите сделать изменение: " << endl;
                int num;
                cin >> num;
                myFileReader.seekg((num - 1) * sizeof(Instrument));
                myFileReader.read((char *) &my, sizeof(Instrument));
                if (my.num == 0) {
                    cout << "Такой записи не существует" << endl;
                    break;
                }
                cout << "Введите новое кол-во: ";
                cin >> my.kolvo;
                myFileReader.seekp((num - 1) * sizeof(Instrument));
                myFileReader.write((char *) &my, sizeof(Instrument));
                myFileReader.flush();
                break;
            }
            //изменяет стоимость
        case(6):
            {
                cout << "Введите номер записи, в которой вы хотите сделать изменение: " << endl;
                int num;
                cin >> num;
                myFileReader.seekg((num - 1) * sizeof(Instrument));
                myFileReader.read((char *) &my, sizeof(Instrument));
                if (my.num == 0) {
                    cout << "Такой записи не существует" << endl;
                    break;
                }
                cout << "Введите новую стоимость: ";
                cin >> my.price;
                myFileReader.seekp((num - 1) * sizeof(Instrument));
                myFileReader.write((char *) &my, sizeof(Instrument));
                myFileReader.flush();
                break;
            }
        default:
            cout << "Неправильное число." << endl;
            break;
        };
        //myFileReader.flush();
        myFileReader.clear();
    }
 
    system("pause");
    return 0;
}
 
int getChoice() {
    cout << "Введите число:" << endl
         << "1 для ввода нового инструмента;" << endl
         << "2 для получения всего списка;" << endl
         << "3 для удаления записей;" << endl
         << "4 изменить название;" << endl
         << "5 изменить количество;" << endl
         << "6 изменить стоимость;" << endl
         << "7 для завершения программы;" << endl;
    int choice;
    cin >> choice;
    return choice;
}
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
20.02.2013, 03:49
Ответы с готовыми решениями:

Чтение/запись из файла
Есть задание: Проблема в том, что после считывание строки char не могу считать строку string struct MyStruct { int ii; ...

Запись и чтение из файла
Вспоминаю как работать с файлами в плюсах. Для примера решил просто записать несколько строк в файл, а затем их считать. Но блин что то оно...

Запись и чтение из файла
Не знаю как подойти. Список товаров, имеющихся на складе, включает в себя наименование товара, количество единиц товара, цену...

11
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
20.02.2013, 05:18
Я такой ошибки не получил, но... Почитайте это: http://www.kalinin.ru/programm... 7_00.shtml
http://habrahabr.ru/post/142662/ Размер вашей структуры 46 байт. sizeof(Instrument) показывает у меня - 48. При записи в файл памяти под структурой будут записываться два лишних байта. Поэтому писать в файл нужно именованные поля структуры, а не память под ней(или использовать специальные приёмы для задания выравнивания: Использование #pragma pack(push,1)... pack(pop)). Читать тоже в именованные поля структуры. Потом, непонятна цель первоначальной записи 100 пустых структур в файл.
1
9 / 9 / 2
Регистрация: 02.11.2012
Сообщений: 153
20.02.2013, 14:21  [ТС]
Ну 100 пустых структур нужно для того, чтобы например они не по порядку записывались, а чтобы например записать в первую и 53 строку и т.д.

Добавлено через 28 минут
Ещё данную ошибку можно воспроизвести так, например ввести такой инструмент
1 molot 10 5
Важно, чтобы после названия шло число двухзначное.
А затем попробовать ввести инструмент с индексом 2, например
2 tyapka 3 4
Тогда программа напишет, что "Данный счёт уже существует", хотя это не верно.

Добавлено через 33 минуты
Но что если даже размер у него 48 байт? Ведь если я например сделал первую запись, то когда я делаю вторую запись я отступаю ведь тоже 48 байт от начала файла, а не 46. Значит всё должно быть ок.
0
Эксперт С++
 Аватар для ITcrusader
179 / 165 / 21
Регистрация: 12.02.2013
Сообщений: 410
20.02.2013, 14:22
kebal, прикрепи файл, с которым работает она)
0
9 / 9 / 2
Регистрация: 02.11.2012
Сообщений: 153
20.02.2013, 15:13  [ТС]
Это не имеет никакого значения, с каким файлом она работает, ведь при запуске программы содержимое файла очищается.
Вот опять же, использовал
#pragma pack(push, 1)
struct Instrument {
...
};
#pragma pack(pop)
Теперь sizeof(Instrument) даёт 46.
И теперь опять если первая запись в виде
1 molot 10 5
то вторая запись уже выдаёт "Данный счёт уже существует".
То есть хоть с использование #pragma pack хоть без первая запись залазит на вторую не понятно почему.

Добавлено через 2 минуты
А что ещё более занимательно, так это при вводе нового инструмента там стоит условие
C++
1
2
3
if (my.num == 0) {
   //сделать запись
}
при печати стоит обратное условие
C++
1
2
3
if (my.num != 0) {
  //напечатать информацию об этом объекте
}
Но при этом оба дают условие false. При этом состояние объекта в первом и втором случае не изменялось...

Добавлено через 34 минуты
в чём может быть проблема?
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
20.02.2013, 15:18
Цитата Сообщение от kebal Посмотреть сообщение
в чём может быть проблема?
C++
1
fstream myFileReader("hardware.dat", ios::in | ios::out | ios::binary);
1
9 / 9 / 2
Регистрация: 02.11.2012
Сообщений: 153
20.02.2013, 15:45  [ТС]
Кстати с ios::binary работает и без #pragma pack. То, о чём я и говорил, просто отступает не 46, а 48 байтов, разве что просто режим был текстовый, потому и не работало.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
20.02.2013, 15:51
Цитата Сообщение от kebal Посмотреть сообщение
Кстати с ios::binary работает и без #pragma pack. То, о чём я и говорил, просто отступает не 46, а 48 байтов, разве что просто режим был текстовый, потому и не работало.
Не работало, мотому что код кривой. Совет, насчёт записи-чтения структур остаётся в силе. #pragma pack это для windows. Писать в файл неизвестно что, не есть Ок.
0
9 / 9 / 2
Регистрация: 02.11.2012
Сообщений: 153
20.02.2013, 15:55  [ТС]
Всмысле "не работало, потому что код кривой"? Я поставил ios::binary и всё теперь работает, значит дело было только в этом. И почему писать в файл неизвестно что? В первой статье, на которую ты дал ссылку очень хорошо написано, почему например получилось не 46, а 48 байт. И опять же, если использовать #pragma pack, то ты разве что уменьшаешь кол-во отступов внутри файла, сокращая его размер. И "тогда был бред", а "сейчас не бред, так как уменьшили кол-во пробелов" как-то не очень стыкуется.
0
290 / 193 / 23
Регистрация: 03.08.2011
Сообщений: 2,824
Записей в блоге: 12
20.02.2013, 15:57
kebal, используйте контейнер map , используйте класс который бы отвечал за хранение и операции над товарами
0
9 / 9 / 2
Регистрация: 02.11.2012
Сообщений: 153
20.02.2013, 16:02  [ТС]
Van111, я всего-лишь учился работать с файлами и я должен был понять почему происходит какая-либо ошибка.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
20.02.2013, 16:04
Цитата Сообщение от kebal Посмотреть сообщение
Всмысле "не работало, потому что код кривой"? Я поставил ios::binary и всё теперь работает, значит дело было только в этом. И почему писать в файл неизвестно что? В первой статье, на которую ты дал ссылку очень хорошо написано, почему например получилось не 46, а 48 байт. И опять же, если использовать #pragma pack, то ты разве что уменьшаешь кол-во отступов внутри файла, сокращая его размер. И "тогда был бред", а "сейчас не бред, так как уменьшили кол-во пробелов" как-то не очень стыкуется.
Я остаютсь при своём мнении. А вольному - воля...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
20.02.2013, 16:04
Помогаю со студенческими работами здесь

Запись и чтение из файла
Здравствуйте не могли бы мне помочь разобраться, что не так. Есть две программы, одна для записи в файл “Writer.exe” а для чтения...

Чтение и запись файла!
Здравствуйте! Вопрос у меня такой: Почему при создании объектов ofstream() и ifstream() в одном файле, значения считанные, например, в...

запись\чтение из файла
У меня несколько вопросов по поводу запись\чтение из файла Как это вообще работает?) Чтобы потом читать из файла надо забивать каждое...

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

Запись и чтение с файла
Подскажите пожалуйста как правильно записать массив в файл и считать его оттуда в другой массив? Если можно пример кода не в чистом с,а...


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

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
Модель сукцессии микоризы
anaschu 24.01.2026
Решили писать научную статью с неким РОманом
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru