С наступающим Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
VadimuSSS
2 / 2 / 0
Регистрация: 23.06.2014
Сообщений: 167
1

Работа с потоками ввода и вывода

16.03.2016, 15:33. Просмотров 252. Ответов 10
Метки нет (Все метки)

Добрый день, всем!
Пишу программу, которая бы хранила определенные данные(в моем случае строка и число) в файле на компьютере. При этом пытаюсь сделать возможность поиска того или иного пункта. допустим ищу слово "hello" и при нахождении такового в файле, будет выведено оно и число, которые было занесено вместе с ним. Проблема возникла тогда, когда я начал передавать данные для внесения через параметры ф-ии. До этого я передавал их путем ввода с клавиатуры и все было хорошо. Сейчас каким-то образом слово, вносимое в файл вносится не корректно. Вместо условного "World" вносится "h/--" или что-то вроде того.
Наверное дело в какой-то специфике с++. Еще я также заметил, что в примере, где не работает - есть проблема с переменной temp. Она не считывается. И я не знаю в чем дело. Буду благодарен помощи, устал уже ломать голову и идей в чем дело - нет.
Приведу примеры кода.

Первый случай, когда все работает:

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
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
 
//---------------------------------------------------------------
 
void ShowFromFile(){
    fstream file("fileik.txt", ios::in | ios::binary);
    if (!file){
        cout << "Problem reading";
        return;
    }
 
    char *word;
    int a;
    int temp;
 
    // В цикле зачитываем содержимое файла
    while (file.read((char*)&a, sizeof(int))){
 
        cout<<"\n\nWord:";
 
        file.read((char*)&temp, sizeof(int));
        word = new char[temp + 1];
        if (!word){
            cout << "Error name";
            return;
        }
 
        file.read((char*)word, temp*sizeof(char));
        word[temp] = '\0';
        cout << word;
 
        cout << "\ndigit";
        cout << a << "\n\n";
        delete[]word;
    }
}
 
//---------------------------------------------------------------
 
void Fill(int digit)
{
    
    char word[100];
    cout << "Enter word: ";
    cin.getline(word, 100);
 
    cout << word << endl;
 
    fstream file("fileik.txt", ios::binary | ios::out | ios::app);
    if (!file)
    {
        cout << "problem";
        return;
    }
 
    int size = strlen(word);
    file.write((char*)&digit, sizeof(int));
    //file >> digit;
 
    file.write((char*)&size, sizeof(int));
    file.write((char*)&word, size*sizeof(char));
    cout << "\ndone\n";
    file.close();
}
 
//---------------------------------------------------------------
 
void Search(char* _word)
{
    fstream file("fileik.txt", ios::in | ios::binary);
    if (!file){
        cout << "Probleam reading";
        return;
    }
 
    char *word;
    int a;
    int temp;
 
    // В цикле зачитываем содержимое файла
    while (file.read((char*)&a, sizeof(int))){
 
            file.read((char*)&temp, sizeof(int));
            word = new char[temp + 1];
            if (!word){
                cout << "Error name";
                return;
            }
 
            file.read((char*)word, temp*sizeof(char));
            word[temp] = '\0';
 
            if (strcmp(word, _word) == 0)
            {
                cout << "We found:\n";
                cout << "Word: " << word << endl << "Digit: " << a << endl;
                delete[]word;
                break;
            }
            delete[]word;
    }
}
 
//---------------------------------------------------------------
 
int main()
{
    Fill(14);
    ShowFromFile();
 
    Search("Nate");
 
 
    return 0;
}
Второй случай, когда ничего не получается:

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
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
 
//---------------------------------------------------------------
 
void ShowFromFile(){
    fstream file("fileik.txt", ios::in | ios::binary);
    if (!file){
        cout << "Problem reading";
        return;
    }
 
    char *word;
    int a;
    int temp;
 
    // В цикле зачитываем содержимое файла
    while (file.read((char*)&a, sizeof(int))){
 
        cout<<"\n\nWord:";
 
        file.read((char*)&temp, sizeof(int));
        word = new char[temp + 1];
        if (!word){
            cout << "Error name";
            return;
        }
 
        file.read((char*)word, temp*sizeof(char));
        word[temp] = '\0';
        cout << word;
 
        cout << "\ndigit";
        cout << a << "\n\n";
        delete[]word;
    }
}
 
//---------------------------------------------------------------
 
void Fill(char* word, int digit)
{
    fstream file("fileik.txt", ios::binary | ios::out | ios::app);
    if (!file)
    {
        cout << "problem";
        return;
    }
 
        //получаем размер строки word
    int size = strlen(word);
       
        
    file.write((char*)&digit, sizeof(int));
 
    file.write((char*)&size, sizeof(int));
 
    file.write((char*)&word, size*sizeof(char));
    cout << "\ndone\n";
    file.close();
}
 
//---------------------------------------------------------------
 
void Search(char* _word)
{
    fstream file("fileik.txt", ios::in | ios::binary);
    if (!file){
        cout << "Probleam reading";
        return;
    }
 
    char *word;
    int a;
    int temp;
 
    // В цикле зачитываем содержимое файла
    while (file.read((char*)&a, sizeof(int))){
 
            file.read((char*)&temp, sizeof(int));
            word = new char[temp + 1];
            if (!word){
                cout << "Error name";
                return;
            }
 
            file.read((char*)word, temp*sizeof(char));
            word[temp] = '\0';
 
            if (strcmp(word, _word) == 0)
            {
                cout << "We found:\n";
                cout << "Word: " << word << endl << "Digit: " << a << endl;
                delete[]word;
                break;
            }
            delete[]word;
    }
}
 
//---------------------------------------------------------------
 
int main()
{
    Fill("Hello", 14);
    ShowFromFile();
 
    Search("Nate"); // условный поиск
 
 
    return 0;
}
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
16.03.2016, 15:33
Ответы с готовыми решениями:

Приведите пример перегруженного ввода / вывода с консольными потоками
наведите пожалуйста пример перегруженного ввода / вывода с консольными...

Ошибка при работе с потоками ввода (вывода) в файл (из файла)
Изучаю перегрузку операторов ввода/вывода с файлом и без. Вылетает такая ошибка...

Работа с файлами на уровне потокового ввода-вывода с буферизацией. С++
Всем здравствуйте. Помогите пожалуйста. Необходимо обеспечить выполнение...

Работа с двоичными файлами, организация ввода-вывода структурированной информации/
Сформировать двоичный файл из элементов, заданной в варианте структуры,...

Организация файлового ввода/вывода (работа с текстовыми и двоичными файлами)
1(работа с текстовыми файлами) -Дан текстовый файл.Переписать в новый файл все...

10
vxg
Модератор
3265 / 2063 / 325
Регистрация: 13.01.2012
Сообщений: 8,004
16.03.2016, 16:12 2
1 не нужно делать &word при записи
2 не очень видно где читается digit
1
yrceus
83 / 83 / 80
Регистрация: 25.08.2013
Сообщений: 333
16.03.2016, 16:16 3
Ага, я тоже нашел)
строка 60
C++
1
file.write((char*)word, size*sizeof(char));
Добавлено через 2 минуты
vxg, а почему интересно в первой версии со взятием адреса корректно происходила запись?
0
VadimuSSS
2 / 2 / 0
Регистрация: 23.06.2014
Сообщений: 167
16.03.2016, 16:39  [ТС] 4
vxg, Кажется заработало! Насчет считывания числа, в 20-ой строке:
C++
1
while (file.read((char*)&a, sizeof(int))){
Можете пожалуйста еще сказать, почему именно из-за ссылки не работало корректно? Для меня изучение ф-ии read и write тяжело дается. fwrite и fread показались намного проще. Везде где находил в справочниках - простое объяснение. Везде передаются два аргумента и это чаровская строка и размер. Но пока я не привел список аргументов к виду read((char*)&a, sizeof(int)) - ничего не заработало. В общем я еще слабо разбираюсь в своем же коде.
0
nd2
2838 / 2405 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
16.03.2016, 16:49 5
Цитата Сообщение от VadimuSSS Посмотреть сообщение
почему именно из-за ссылки не работало корректно?
Нет тут ссылок.
Цитата Сообщение от VadimuSSS Посмотреть сообщение
Но пока я не привел список аргументов к виду read((char*)&a, sizeof(int)) - ничего не заработало.
У тебя, в коде, разве по-другому было?
0
VadimuSSS
2 / 2 / 0
Регистрация: 23.06.2014
Сообщений: 167
16.03.2016, 17:04  [ТС] 6
nd2, В коде у меня также было. Просто везде где я видел листинг данной ф-ии мне встречалось
C++
1
2
 // write to outfile
  outfile.write (buffer,size);
и никаких типов данных вроде (char*) и & не было.
ссылок тут нет? что тогда значит &a?
0
nd2
2838 / 2405 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
16.03.2016, 17:15 7
Цитата Сообщение от VadimuSSS Посмотреть сообщение
и никаких типов данных вроде (char*) и & не было.
Это тогда, когда первый параметр и так является указателем на char (например, имя массива char, которое неявно преобразуется, в этом случае, в указатель на char), как, например, у тебя word (там можно не приводить к char*).
Цитата Сообщение от VadimuSSS Посмотреть сообщение
file.read((char*)word, temp*sizeof(char));
C++
1
file.read(word, temp);
Добавлено через 1 минуту
Цитата Сообщение от VadimuSSS Посмотреть сообщение
ссылок тут нет? что тогда значит &a?
Взятие адреса переменной a . Этот адрес приводится к char*.
1
yrceus
83 / 83 / 80
Регистрация: 25.08.2013
Сообщений: 333
16.03.2016, 17:25 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
void Fill(int digit)
{
    
    char word[100];
    cout << "Enter word: ";
    cin.getline(word, 100);
 
    cout << word << endl;
 
    fstream file("fileik.txt", ios::binary | ios::out | ios::app);
    if (!file)
    {
        cout << "problem";
        return;
    }
 
    int size = strlen(word);
    file.write((char*)&digit, sizeof(int));
    //file >> digit;
 
    file.write((char*)&size, sizeof(int));
    file.write((char*)&word, size*sizeof(char));// вот, взятие адреса, но записывает
    cout << "\ndone\n";
    file.close();
}
0
nd2
2838 / 2405 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
16.03.2016, 17:42 9
Цитата Сообщение от yrceus Посмотреть сообщение
а почему в первой версии тогда так работало?
C++
1
2
3
    char word[100];
    std::cout << (void*)(&word) << std::endl;
    std::cout << (void*)(word)<< std::endl;
Добавлено через 4 минуты
C++
1
2
3
    char* word = new char[100];
    std::cout << (void*)(&word) << std::endl;
    std::cout << (void*)(word) << std::endl;
1
VadimuSSS
2 / 2 / 0
Регистрация: 23.06.2014
Сообщений: 167
16.03.2016, 17:49  [ТС] 10
nd2, ааа...так это приведение типов...что-то читал об этом.

Добавлено через 3 минуты
Еще немного вашего внимания

Код, который я показывал выше, это что-то вроде экспериментов над новоизученным материалом.
Вот главная программа. Ее смысл таков же. Только полей побольше и в классе все. Я думал что в ней проблема такая же, как и в том предыдущем, но нет...я тут снова делаю что-то не так.
Сначала думал что проблема в ф-ии читающей файлы, теперь склоняюсь к тому, что я напортачил где-то в конструкторе или ф-ии Add

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
193
194
195
196
197
198
199
200
201
202
203
204
205
#include <iostream>
#include <fstream>
#include <vector>
 
using namespace std;
 
class Catalog
{
private:
    char* name;
    char* owner;
    long number;
    char* address;
    char* activity;
public:
 
    Catalog()
    {
        name = 0;
        owner = 0;
        number = 0;
        address = 0;
        activity = 0;
    }
 
    //--------------------------------------------------------------
 
    void Add(char* _name, char* _owner, long _number, char* _address, char* _activity)
    {
        name = new char[strlen(_name) + 1];
        strcpy(name, _name);
 
        //delete owner;
        owner = new char[strlen(_owner) + 1];
        strcpy(owner, _owner);
        
        //delete address;
        address = new char[strlen(_address) + 1];
        strcpy(address, _address);
 
        //delete activity;
        activity = new char[strlen(_activity) + 1];
        strcpy(activity, _activity);
 
        number = _number;
 
        SaveToFile(name, owner, number, address, activity);
    }
 
    //--------------------------------------------------------------
    void SaveToFile(char* _name, char* _owner, long _number, char* _address, char* _activity)
    {
        int size = 0;
        fstream catalog("catalog.txt", ios::out | ios::binary | ios::app);
        if (!catalog){
            cout << "Error in file opening";
            exit(1);
        }
        
        //name
        size = strlen(_name);
        catalog.write((char*)&size, sizeof(int));
        catalog.write((char*)_name, size*sizeof(char));
 
        //owner
        size = strlen(_owner);
        catalog.write((char*)&size, sizeof(int));
        catalog.write((char*)_owner, size*sizeof(char));
        
        //number
        catalog.write((char*)&_number, sizeof(number));
 
        //address
        size = strlen(_address);
        catalog.write((char*)&size, sizeof(int));
        catalog.write((char*)_address, size*sizeof(char));
 
        //activity
        size = strlen(_activity);
        catalog.write((char*)&size, sizeof(int));
        catalog.write((char*)_activity, size*sizeof(char));
        
 
        catalog.close();
        
    }
 
    //--------------------------------------------------------------
 
    void PrintInfo()
    {
        cout << "Information about " << name << endl;
        cout << "Owner: " << owner << endl;
        cout << "Address: " << address << endl;
        cout << "Activity: " << activity << endl;
        cout << "Phone number: " << number << endl;
    }
 
    //--------------------------------------------------------------
 
    void ShowFromFile(){
        fstream catalog("catalog.txt", ios::in | ios::binary);
 
        if (!catalog)
            cout<<"Error in file opening.";
        
        char *_name, *_owner, *_address, *_activity;
        int a;
        int temp;
 
        // В цикле зачитываем содержимое файла
        while (catalog.read((char*)&a, sizeof(int))){
 
            // *****read name*****
 
            cout<<"Name:";
 
            catalog.read((char*)&temp, sizeof(int));
 
            cout << "\ntemp: " << temp << endl;
            
            _name = new char[temp + 1];
 
            if (!_name){
                cout<<"error with memory 1";
            }
 
            catalog.read((char*)_name, temp*sizeof(char));
            _name[temp] = '\0';
            cout << _name;
 
            //  *****read owner*****
            
            cout<<"Owner: ";
 
            catalog.read((char*)&temp, sizeof(int));
            _owner = new char[temp + 1];
 
            cout << "\ntemp: " << temp << endl;
 
            if (!_owner){
                cout << "error with memory 2";
            }
 
            catalog.read((char*)_owner, temp*sizeof(char));
            _owner[temp] = '\0';
            cout << _owner;
 
            // *****read number(?)
            
            cout << "Number: ";
            cout << a << "\n";
 
            // *****read address******
 
            cout << "Address: ";
 
            catalog.read((char*)&temp, sizeof(int));
            _address = new char[temp + 1];
 
            cout << "\ntemp: " << temp << endl;
 
            if (!_address){
                cout << "error with memory 2";
            }
 
            catalog.read((char*)_address, temp*sizeof(char));
            _address[temp] = '\0';
            cout << _address;
 
            // *****read activity*****
 
            cout << "Activity: ";
 
            catalog.read((char*)&temp, sizeof(int));
            _activity = new char[temp + 1];
 
            cout << "\ntemp: " << temp << endl;
 
            if (!_activity){
                cout << "error with memory 2";
            }
 
            catalog.read((char*)_activity, temp*sizeof(char));
            _activity[temp] = '\0';
            cout << _activity;
 
            // ***** *****
 
            delete[]name;
            delete[]owner;
        }
    }
 
    //--------------------------------------------------------------
 
};
 
int main()
{
    Catalog a;
    a.Add("Company", "John Johnson", 9834522, "USA, NY 5th avenue", "medicine");
    a.ShowFromFile();
    return 0;
}
0
nd2
2838 / 2405 / 1057
Регистрация: 29.01.2016
Сообщений: 8,046
16.03.2016, 17:54 11
Цитата Сообщение от VadimuSSS Посмотреть сообщение
так это приведение типов...
Функции бинарного чтения/записи требуют первым параметром char*, или const char* (так как происходит чтение/запись байтов (char), то и память для этого должна быть такая же указана). Если адрес, передаваемый в эти функции, не char*, то нужно делать явное приведение.
1
16.03.2016, 17:54
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
16.03.2016, 17:54

Работа с структурами: выполните, используя файловые потоки для ввода/вывода
Используя тип данных запись с именем PRICE, содержащую следующие поля: • TOVAR...

работа с потоками
Добрый вечер! Есть файл txt, состоит из символов, чисел, необходимо его...

Работа с потоками
Добрый вечер. Возникла такая проблема: в консольном приложении...


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

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

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