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

Работа с бинарными файлами (программка дважды записывает последнее число) - C++

Восстановить пароль Регистрация
 
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
09.03.2013, 22:54     Работа с бинарными файлами (программка дважды записывает последнее число) #1
Добрый день, помогите пожалуйста с такой ситуацией:
написал програмку для заполнения бинарного файла рандомными числами (их количество вводится в начале программы):
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
#include <iostream>
#include <fstream>
#include <time.h>
using namespace std;
 
void random(int N){
    ofstream file("resource.bin", ios::binary|ios::out);
    srand(time(NULL));
    int digit;
    for(int i = 1;i <= N;i++){
        digit = +60-rand()%100;
        file.write((char*)&digit, sizeof digit);
    }
    file.close();
}
 
int main(int argc, char *argv[]){
    setlocale(LC_ALL, "Russian");
    int N;
    cout << "Число чисел  в файле: ";
    cin >> N;
    random(N);
    system("PAUSE");
    return 0;
}
решил проверить содержимое созданного файла и столкнулся с проблемой, которую так и не решил. Суть её в том, что программка дважды записывает последнее число. Например: -36 34 -17 38 -21 -38 -38.
Код программы которой я проверяю файл:
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
#include <iostream>
#include <fstream>
using namespace std;
 
int readFile(string name){
    ifstream file(name, ios::binary|ios::in);
    ofstream tmp("tmp", ios::binary|ios::out);
    int digit;
    if(file.is_open()){ 
        while(!file.eof()){
            file.read((char*)&digit, sizeof digit);
            cout << digit << " ";
        }
        cout << endl;
    }
    file.close();
            return 0;
}
 
int main(int argc, char *argv[]){
    setlocale(LC_ALL, "Russian");
             readFile("resource.bin");
    system("PAUSE");
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.03.2013, 22:54     Работа с бинарными файлами (программка дважды записывает последнее число)
Посмотрите здесь:

C++ Работа с бинарными файлами
Что за ошибка?? (Работа с бинарными файлами) C++
Работа с текстовыми и бинарными файлами C++
Работа с текстовыми и бинарными файлами C++
C++ Работа с Бинарными файлами
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
09.03.2013, 23:43     Работа с бинарными файлами (программка дважды записывает последнее число) #2
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Суть её в том, что программка дважды записывает последнее число.
А Вы уверены, что записывает? Может считывает?
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
while(!file.eof()){
file.read((char*)&digit, sizeof digit);
cout << digit << " ";
}
Дабы никаких чудес не возникало, проверку на конец файла следует делать непосредственно после чтения из файла, а не до него.
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
10.03.2013, 13:58  [ТС]     Работа с бинарными файлами (программка дважды записывает последнее число) #3
Я вот тоже пришел к выводу что считывает неправильно, но даже с циклом с постусловием чуда не произошло
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
10.03.2013, 14:10     Работа с бинарными файлами (программка дважды записывает последнее число) #4
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
C++
1
2
3
4
while(!file.eof()){
* * * * * * file.read((char*)&digit, sizeof digit);
* * * * * * cout << digit << " ";
* * * * }
C++
1
2
3
4
5
6
7
8
while (1)
{
   file.read((char*)&digit, sizeof(digit);
   if (file.eof())
      break;
   else
      cout << digit << " ";
}
Добавлено через 2 минуты
Хотя здесь можно элегантнее, учитывая, что read возвращает количество считанных блоков
C++
1
2
while (file.read((char*)&digit, sizeof(digit)))
   cout << digit << " ";
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.03.2013, 14:22     Работа с бинарными файлами (программка дважды записывает последнее число) #5
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Я вот тоже пришел к выводу что считывает неправильно, но даже с циклом с постусловием чуда не произошло
И не произойдёт, потому что до проверки условия будет вывод cout, а считался конец файла, поэтому в digit ничего не поместилось (осталось старое значение, которое и выведется второй раз).
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
10.03.2013, 16:32  [ТС]     Работа с бинарными файлами (программка дважды записывает последнее число) #6
ЯснопонятноВсем спасибо

Добавлено через 24 минуты
Теперь запара с записью/чтением структур из бинарного файла
Заполняю файл этим:
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
struct MyStruct
{
    string name;
    int age;
};
 
int main(){
    ofstream file("resource.bin", ios::binary|ios::out);
    MyStruct im;
    string name;int age;
    cin >> name;
    im.name = name;
    cin >> age;
    im.age = age;
    file.write((char*)&im, sizeof(im));
    file.close();
    system("PAUSE");
    return 0;
}
Читаю этим:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
struct MyStruct
{
    string name;
    int age;
};
 
int main(){
    ifstream file("resource.bin", ios::binary|ios::in);
    MyStruct im;
    if(file.is_open())
        file.read((char*)&im, sizeof(im));
    else cout << "err" << endl;
    cout << im.name << " " << im.age << endl;
    system("PAUSE");
    return 0;
}
Все работает (вторая программа считывает структуру и выводит на экран), но перед выходом она вылетает (появляется окошко "Прекращена работа програмы..."). В чем мой косяк?
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11817 / 6796 / 769
Регистрация: 27.09.2012
Сообщений: 16,867
Записей в блоге: 2
Завершенные тесты: 1
10.03.2013, 16:34     Работа с бинарными файлами (программка дважды записывает последнее число) #7
Считывайте из файла каждое поле по отдельности.

P.S. И это только во-первых
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
10.03.2013, 16:40  [ТС]     Работа с бинарными файлами (программка дважды записывает последнее число) #8
Не помогло
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.03.2013, 16:55     Работа с бинарными файлами (программка дважды записывает последнее число) #9
Зачем вам тут бинарное чтение / запись? Используйте обычное (getline(), cin >>, cout <<). У вас в структуре объект string. Вы бинарно записываете память под структурой в файл. Что там записывается вообще не известно.

Добавлено через 3 минуты
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Не помогло
Покажите как делаете.
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
10.03.2013, 17:06  [ТС]     Работа с бинарными файлами (программка дважды записывает последнее число) #10
Само задание выглядит так:
Расписание движение поездов хранится в бинарном файле и содержит информацию: пункт назначения, номер поезда, тип поезда, время отправления, время в пути. Вывести сведения о поездах, следующих в Москву в определенный временной период. Считать данные из файла в односвязный линейный список. Найти поезд определенного типа, доезжающий до Москвы за наименьшее время. Выяснить, какие поезда отправляются после 22 часов.

Написал, но считывал из текстового файла, а теперь из бинарного пытаюсь
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11817 / 6796 / 769
Регистрация: 27.09.2012
Сообщений: 16,867
Записей в блоге: 2
Завершенные тесты: 1
10.03.2013, 17:08     Работа с бинарными файлами (программка дважды записывает последнее число) #11
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Не помогло
Ну если Вы продолжили делать так:
C++
1
file.read((char*)&im.name, sizeof(im.name));
то естественно, что не помогло
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.03.2013, 17:31     Работа с бинарными файлами (программка дважды записывает последнее число) #12
Проблема в том, что когда вы бинарно записываете в файл память под объектом string, то не понятно, что записывается (зависит от реализаци string). Может там указатель на строку, которая находится совсем в другом месте. Записали вы это указатель в файл. Потом считали его и пытаетесь через него что-то вывести. Отладчиком, ради интереса, посмотрите, что у вас в name перед выводом находится.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11817 / 6796 / 769
Регистрация: 27.09.2012
Сообщений: 16,867
Записей в блоге: 2
Завершенные тесты: 1
10.03.2013, 17:34     Работа с бинарными файлами (программка дважды записывает последнее число) #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Потом считали его
Считали куда? Вникуда. Никто не выделял память под символы в im.name
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
10.03.2013, 17:36  [ТС]     Работа с бинарными файлами (программка дважды записывает последнее число) #14
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
struct MyStruct
{
    string name;
    int age;
};
 
int main(){
    ifstream file("resource.bin", ios::binary|ios::in);
    MyStruct im;
    if(file.is_open()){
        file.read((char*)&im.name, sizeof(im.name));
        file.read((char*)&im.age, sizeof(im.age));
    }else cout << "err" << endl;
    cout << im.name << " " << im.age << endl;
    system("PAUSE");
    return 0;
}
Добавлено через 1 минуту
То есть лучше отказаться от класса string?
Croessmah
10.03.2013, 17:39
  #15

Не по теме:

Цитата Сообщение от Plu6e4ka Посмотреть сообщение
То есть лучше отказаться от класса string?
научится с ним работать.

Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 15
10.03.2013, 17:40  [ТС]     Работа с бинарными файлами (программка дважды записывает последнее число) #16
Ок
alsav22
5282 / 4801 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.03.2013, 18:56     Работа с бинарными файлами (программка дважды записывает последнее число) #17
Plu6e4ka, в какой среде делаете?

Добавлено через 52 минуты
Как-то так:
Кликните здесь для просмотра всего текста
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
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
 
struct MyStruct
{
    string name;
    int age;
};
 
int main()
{
    MyStruct im;
    
    cin >> im.name;
    cin >> im.age;
    
    ofstream fout("resource.bin", ios::binary | ios::out);
    int size_name = im.name.size();
    // первым в файл записываем размер строки (количество символов)
    fout.write((const char*)&size_name, sizeof(size_name));
    // потом символы строки
    fout.write(im.name.c_str(), size_name);
    
    fout.write((const char*)&im.age, sizeof(im.age));
    fout.close();
    
    MyStruct im2;
    
    ifstream fin("resource.bin", ios::binary | ios::in);
    if(fin.is_open())
    {
        // читаем размер строки (количество символов записанных в файл)
        int size_name;
        fin.read((char*)&size_name, sizeof(size_name));
        
        // выделяем память под строку
        im2.name.resize(size_name);
        
        // читаем символы строки
        fin.read((char*)im2.name.c_str(), size_name);
        
        fin.read((char*)&im2.age, sizeof(im2.age));
        fin.close();
    }
    else cout << "err" << endl;
    
    cout << im2.name << " " << im2.age << endl;
    
    system("PAUSE");
    return 0;
}

Но, по моему, бинарно записывать объекты string в файл, не есть хорошо.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.03.2013, 19:51     Работа с бинарными файлами (программка дважды записывает последнее число)
Еще ссылки по теме:

C++ Работа с бинарными файлами. Определение четности
Visual c++. Работа с бинарными файлами и структурами C++
Работа с бинарными файлами и структурами C++

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

Или воспользуйтесь поиском по форуму:
kazak
 Аватар для kazak
3029 / 2350 / 155
Регистрация: 11.03.2009
Сообщений: 5,401
10.03.2013, 19:51     Работа с бинарными файлами (программка дважды записывает последнее число) #18
Plu6e4ka, если хотите string, сначала придется разобраться с понятиями POD-структура неPOD-структура и открыть новый термин - сериализация данных
Yandex
Объявления
10.03.2013, 19:51     Работа с бинарными файлами (программка дважды записывает последнее число)
Ответ Создать тему
Опции темы

Текущее время: 08:16. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru