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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
lotos580
1 / 1 / 1
Регистрация: 25.05.2012
Сообщений: 60
#1

Неправильно записывается бинарник - C++

10.07.2014, 19:32. Просмотров 349. Ответов 11
Метки нет (Все метки)

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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
using namespace std;
 
class Good
{
public:
    Good(const int = 0, const string = "", const int = 0, const double = 0.0);
    int getID() {return ID;}
    string getTitle() {return title;}
    int getAmount() {return amount;}
    double getPrice() {return price;}
private:
    int ID;
    string title;
    int amount;
    double price;
};
 
Good::Good(const int initID, const string _title, const int _amount, const double _price)
{
    ID = (initID > 0) ? initID : 0;
    title = _title;
    amount = _amount;
    price = _price;
}
 
void showInstruction()
{
    cout << "1 - add new good" << endl
         << "2 - delete good" << endl
         << "3 - change amount" << endl
         << "4 - change price" << endl
         << "5 - change title" << endl
         << "6 - record data base" << endl
         << "7 - end programm" << endl;
}
 
int getAction()
{
    int action;
    cout << "Enter 1 - 7: ";
    cin >> action;
    while(action > 6 && action < 1)
        cin >> action;
    return action;
}
 
bool addNewElement()
{
    ofstream myFile("file.bin", ios::binary|ios::app);
    if(!myFile)
    {
        cerr << "ERROR: can't open myFile as ifstream at << bool addNewElement() >>" << endl;
        exit(1);
    }
    cout << "Enter ID, title, amount, price: ";
    int ID;
    string title;
    int amount;
    double price;
    cin >> ID >> title >> amount >> price;
    Good product(ID, title, amount, price);
 
    myFile.seekp((ID - 1) * sizeof(product)); 
    myFile.write(reinterpret_cast<char*>(&product), sizeof(product)); // else record element
    
    myFile.close();
    return true;
}
 
void recordDataBase()
{
    ifstream myFile("file.bin", ios::binary); // открываем для чтения
    if(!myFile)
    {
        cerr << "ERROR: can't open myFile as ofstream at << void recordDataBase() >>" << endl;
        exit(1);
    }
    ofstream recordFile("recordFile.txt", ios::out);
    if(!recordFile)
    {
        cerr << "ERROR: can't open recordFile as ifstream at << void recordDataBase() >>" << endl;
        exit(1);
    }
    recordFile << setw(30) << "ID" << setw(30) << "TITLE"
            << setw(30) << "AMOUNT" << setw(30) << "PRICE\n\n";
    myFile.seekg(0);
    Good empty; // create client with no information
    while(true)
    {
        myFile.read(reinterpret_cast<char*>(&empty), sizeof(empty));
        if(myFile.eof())
            break;
        if(empty.getID() == 0)
            continue;
        recordFile << setw(30) << empty.getID() << setw(30) << empty.getTitle()
            << setw(30) << empty.getAmount() << setw(30) << fixed 
            << setprecision(2) << (double)empty.getPrice() << endl;
    }
}
 
bool deleteElement()
{
    ofstream myFileWrite("file.bin", ios::binary);
 
    if(!myFileWrite)
    {
        cerr << "ERROR: can't open myFileWrite as ifstream at << bool deleteElement() >>" << endl;
        exit(1);
    }
    ifstream myFileRead("file.bin", ios::binary);
    if(!myFileRead)
    {
        cerr << "ERROR: can't open myFileRead as ifstream at << bool deleteElement() >>" << endl;
        exit(1);
    }
    cout << "Enter ID to delete: ";
    int ID;
    cin >> ID;
    while(ID < 0)
    {
        cout << "incorrect ID, try again" << endl;
        cin >> ID;
    }
    Good empty;
    myFileRead.seekg((ID - 1) * sizeof(empty));
    myFileRead.read(reinterpret_cast<char*>(&empty), sizeof(empty));
    
    if(empty.getID() == 0)
        return false;
    
    Good noinformation(0);
    myFileWrite.seekp((ID - 1) * sizeof(empty));
    myFileWrite.write(reinterpret_cast<char*>(&noinformation), sizeof(noinformation));
    myFileRead.close();
    myFileWrite.close();
    return true;
}
 
void changeAmount()
{
}
 
void changePrice()
{
}
 
void changeTitle()
{
}
 
int main()
{
    showInstruction();
    int action = getAction();
    while(action != 7)
    {
        switch(action)
        {
        case 1:
            if(addNewElement())
                cout << setw(30) << "Record success" << endl;
            else
                cout << "This ID is already busy" << endl;
            break;
        case 2:
            if(deleteElement())
                cout << setw(30) << "Delete successfull" << endl;
            else
                cout << "Error. Can't delete" << endl;
            break;
        case 3:
            changeAmount();
            break;
        case 4:
            changePrice();
            break;
        case 5:
            changeTitle();
            break;
        case 6:
            recordDataBase();
            break;
        }
        action = getAction();
    }
    return 0; 
}
Если записываем несколько товаров, они почему-то идут по порядку(то есть друг за другом), хотя должны по порядку по ключу (ID).
Помогите, пожалуйста.

Добавлено через 25 секунд
Столкнулся в процессе написания программы...

Добавлено через 6 минут
Проблема непосредственно при создании нового товара(пункт #1 в меню) и записи в txt (п.6).
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
10.07.2014, 19:32
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Неправильно записывается бинарник (C++):

Неправильно записывается символ в файл - C++
ПОМОГИТЕ КТО ЧЕМ МОЖЕТ!!! Зашифровал значит текст.Дальше его расшифровую.Расшифровал Получил ASCII код символа.Пишу что-то типа: int...

Криво читается бинарник - C++
Здравия желаю! #include &lt;iostream&gt; #include &lt;fstream&gt; using namespace std; void main() { char l=6,c=3,b; fstream...

Как побайтно считать бинарник? - C++
Как побайтно считать бинарник? Именно в переменную тип char.

Запись структуры с строкой в бинарник - C++
Здравствуйте, уважаемые форумчане! Интересовал вопрос записи структуры, в который есть string, в бинарный файл. Нашел на форуме код и...

GCC 4.7 компилируется, но не запускается бинарник - C++
Где облажался? int main() { int a = {5,}; int b = {7,}; int sum=0; for(int i = 1; i &lt; 200; i++)

Запись в бинарник и его чтение - C++
Привет всем, задача состоит в том, что нужно записать в бинарник сведения о сканерах и считать их из него. Проблема в том что нужно в...

11
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
10.07.2014, 19:56 #2
Цитата Сообщение от lotos580 Посмотреть сообщение
Проблема непосредственно при создании нового товара(пункт #1 в меню) и записи в txt (п.6).
Класс содержит стандартную строку, которая в свою очередь, содержит указатель динамический массив на куче. По этому, так:

C++
1
myFile.write(reinterpret_cast<char*>(&product), sizeof(product));
Писать этот объект нельзя. Пиши операторы ввода-вывода в поток и обратно.
0
lotos580
1 / 1 / 1
Регистрация: 25.05.2012
Сообщений: 60
10.07.2014, 20:00  [ТС] #3
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Писать этот объект нельзя. Пиши операторы ввода-вывода в поток и обратно.
это решение проблемы?

Добавлено через 14 секунд
не помогло...
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
10.07.2014, 20:06 #4
Цитата Сообщение от lotos580 Посмотреть сообщение
не помогло...
Читать его так тоже нельзя, мне казалось, это очевидно. Запись и чтение должны быть симметричны.
0
DrOffset
7315 / 4415 / 1000
Регистрация: 30.01.2014
Сообщений: 7,252
10.07.2014, 20:12 #5
Цитата Сообщение от lotos580 Посмотреть сообщение
не помогло...
За 14 секунд то, что он предложил не сделать.
А предложил он конкретно вот это.
Каждое поле в классе Good нужно сохранять отдельно, объединив это оператором ввода в поток.
Примерная иллюстрация:
C++
1
2
3
4
5
std::ostream & operator<<(std::ostream & out, Good const & x)
{
    out << x.ID << x.title << x.amount << x.price;
    return out;
}
И аналогичная процедура чтения (тоже лишь иллюстрация):
C++
1
2
3
4
5
std::istream & operator>>(std::istream & in, Good & x)
{
    in >> x.ID >> x.title >> x.amount >> x.price;
    return in;
}
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
10.07.2014, 20:25 #6
Цитата Сообщение от DrOffset Посмотреть сообщение
А предложил он конкретно вот это.
Да, имелось в виду это. Но не обязательно, геттеры есть, можно сеттеры написать. Главное, нельзя писать этот класс как тупую структуру .
0
lotos580
1 / 1 / 1
Регистрация: 25.05.2012
Сообщений: 60
10.07.2014, 20:32  [ТС] #7
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Писать этот объект нельзя. Пиши операторы ввода-вывода в поток и обратно.
Возможно я не так вас понял...
Нельзя так записывать из-за члена класса string в классе, верно?
0
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
10.07.2014, 20:36 #8
Цитата Сообщение от lotos580 Посмотреть сообщение
Нельзя так записывать из-за члена класса string в классе, верно?
Да. sizeof(std::string) имеет мало общего с размером данных строки.
1
lotos580
1 / 1 / 1
Регистрация: 25.05.2012
Сообщений: 60
10.07.2014, 22:22  [ТС] #9
Цитата Сообщение от uglyPinokkio Посмотреть сообщение
Да. sizeof(std::string) имеет мало общего с размером данных строки.
а если, допустим, такая вариация программы, без string в классе

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
#include <iostream>
#include <string>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
using namespace std;
 
class Good
{
public:
    Good(const int = 0);
    int getID() {return ID;}
private:
    int ID;
};
 
Good::Good(const int initID)
{
    ID = (initID > 0) ? initID : 0;
}
 
void showInstruction()
{
    cout << "1 - add new good" << endl
         << "2 - delete good" << endl
         << "3 - change amount" << endl
         << "4 - change price" << endl
         << "5 - change title" << endl
         << "6 - record data base" << endl
         << "7 - end programm" << endl;
}
 
void add(ofstream& f)
{
    int id;
    cout << "enter id: ";
    cin >> id;
 
    Good object(id);
    f.seekp((id - 1) * sizeof(object));
    f.write(reinterpret_cast<char*>(&object), sizeof(object));
    cout << "success" << endl;
}
 
void del(ofstream& f)
{
    int id;
    cout << "enter id: ";
    cin >> id;
 
    Good object(0);
    cout << "*************" << object.getID() << endl;
    f.seekp((id - 1) * sizeof(object));
    f.write(reinterpret_cast<char*>(&object), sizeof(object));
    cout << "success" << endl;
}
 
void record(ofstream& f)
{
    f.close(); /////////////////////////////////////////////////////////////////////////////////////////////////////
 
    ifstream file("file.bin", ios::binary);
    file.seekg(0);
    Good object;
    
    ofstream rec("rec.txt", ios::out);
 
    while(true)
    {
        file.read(reinterpret_cast<char*>(&object), sizeof(object));
        if(file.eof())
            exit(1);
        if(object.getID() != 0)
            rec << object.getID() << endl;
    }
    exit(1);
}
 
int main()
{
    ofstream outFile("file.bin", ios::app|ios::binary);
    if(!outFile)
    {
        cerr << "error 1" << endl;
        exit(1);
    }
    showInstruction();
    int action;
    cout << "enter action";
    cin >> action;
    while(action != 7)
    {
        
        switch(action)
        {
        case 1:
            add(outFile);
            break;
        case 2:
            del(outFile);
            break;
        case 6:
            record(outFile);
            break;
        }
        cout << "enter action";
        cin >> action;
    }
    return 0;
}
Почему-то функция удаления не перезаписывает бинарный файл (удаляемый объект должен заменяться объектом с id = 0, соответственно не должен заноситься в результирующий файл rec.txt, по при удалении он остается...
Что тут не так?
0
Alex5
1056 / 720 / 108
Регистрация: 12.04.2010
Сообщений: 1,847
10.07.2014, 23:37 #10
Цитата Сообщение от lotos580 Посмотреть сообщение
C++
1
ofstream myFile("file.bin", ios::binary|ios::app);
Видимо, если ios::app, запись всегда производится в конец файла. Вот так функция seekp() работает:
C++
1
    ofstream myFile("file.bin", ios::binary|ios::in);
Другой вопрос - содержимое файла. Сейчас попробовал в VS:
C++
1
2
3
4
5
6
7
8
// Содержимое существующего файла будет удалено.
 
        ofstream fstr( name, ios::binary ); 
        ofstream fstr( name, ios::binary | ios::ate ); 
 
// Сохранится 
        ofstream fstr( name, ios::binary | ios::app ); 
        ofstream fstr( name, ios::binary | ios::in );
1
uglyPinokkio
326 / 229 / 41
Регистрация: 30.05.2014
Сообщений: 682
11.07.2014, 06:57 #11
Цитата Сообщение от lotos580 Посмотреть сообщение
а если, допустим, такая вариация программы, без string в классе

string можно заменить на символьный массив.

Цитата Сообщение от lotos580 Посмотреть сообщение
Что тут не так?
Пока не знаю, для начала нужно проверить позиционирование

C
1
f.seekp((id - 1) * sizeof(object));
Вот тут прочитать объект и проверить Id
1
lotos580
1 / 1 / 1
Регистрация: 25.05.2012
Сообщений: 60
11.07.2014, 14:28  [ТС] #12
Цитата Сообщение от Alex5 Посмотреть сообщение
ofstream fstr( name, ios::binary | ios::in );
а вот за это огромное спасибо работает отлично!
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.07.2014, 14:28
Привет! Вот еще темы с ответами:

Прочитать бинарник картинки через std::cin - C++
Здравствуйте дорогие форумчане! У меня возникла такая не тривиальная задача, вот собственно в чем фишка: Нужно написать на С++...

Где скачать бинарник haartraining для opencv - C++
Где скачать бинарник haartraining для opencv ?

Проверьте задачку по циклам, неправильно работает. [думаю что неправильно] - C++
Спасибо что решили зайти. Задание выгладит так: http://*******/PW95p А результат выплнения: http://*******/KwhuS #include...

Как компилировать программу C++ или код в бинарник (что бы запускался без участия ОС) - C++
Помогите пожалуйста как компилировать прогу написанную на с++ или код в бинарник (что бы запускался без участия ОС) И сразу второй вопрос...


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

Или воспользуйтесь поиском по форуму:
12
Yandex
Объявления
11.07.2014, 14:28
Ответ Создать тему
Опции темы

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