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

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

Войти
Регистрация
Восстановить пароль
 
 
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 18
#1

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

09.03.2013, 22:54. Просмотров 832. Ответов 17
Метки нет (Все метки)

Добрый день, помогите пожалуйста с такой ситуацией:
написал програмку для заполнения бинарного файла рандомными числами (их количество вводится в начале программы):
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;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.03.2013, 22:54
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Работа с бинарными файлами (программка дважды записывает последнее число) (C++):

Работа с бинарными файлами - C++
Помогите решить проблему. Задача: создать файл записать в него 10 структур и закрыть, затем добавить еще 3, а после вывести их все на...

Работа с бинарными файлами - C++
Задача такова : нужно записать созданные объекты класса в бинарный фал а затем прочитать их же из файла и вывести на экран. Код написал,...

Работа с бинарными файлами - C++
Создать текстовый файл с произвольным текстом. Разработать программу, которая выводит на экран по желанию пользователя: а) N первых строк...

Работа с бинарными файлами - C++
Написать программу для обработки информации о планшетах. Информация включает следующие данные: - Компания-производитель. - Размер...

Работа с Бинарными файлами - C++
Помогите сделать сохранение не могу разобраться :( Почему в этом коде #include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;windows.h&gt; ...

Работа с бинарными файлами - C++
Создать бинарный файл с информацией о работниках предприятия: 1) фамилия 2) возраст 3) образование 4) должность 5) пол Вывести...

17
kazak
3048 / 2369 / 160
Регистрация: 11.03.2009
Сообщений: 5,436
Завершенные тесты: 1
09.03.2013, 23:43 #2
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Суть её в том, что программка дважды записывает последнее число.
А Вы уверены, что записывает? Может считывает?
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
while(!file.eof()){
file.read((char*)&digit, sizeof digit);
cout << digit << " ";
}
Дабы никаких чудес не возникало, проверку на конец файла следует делать непосредственно после чтения из файла, а не до него.
0
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 18
10.03.2013, 13:58  [ТС] #3
Я вот тоже пришел к выводу что считывает неправильно, но даже с циклом с постусловием чуда не произошло
0
kazak
3048 / 2369 / 160
Регистрация: 11.03.2009
Сообщений: 5,436
Завершенные тесты: 1
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 << " ";
1
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.03.2013, 14:22 #5
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Я вот тоже пришел к выводу что считывает неправильно, но даже с циклом с постусловием чуда не произошло
И не произойдёт, потому что до проверки условия будет вывод cout, а считался конец файла, поэтому в digit ничего не поместилось (осталось старое значение, которое и выведется второй раз).
1
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 18
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;
}
Все работает (вторая программа считывает структуру и выводит на экран), но перед выходом она вылетает (появляется окошко "Прекращена работа програмы..."). В чем мой косяк?
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
10.03.2013, 16:34 #7
Считывайте из файла каждое поле по отдельности.

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

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

Написал, но считывал из текстового файла, а теперь из бинарного пытаюсь
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
10.03.2013, 17:08 #11
Цитата Сообщение от Plu6e4ka Посмотреть сообщение
Не помогло
Ну если Вы продолжили делать так:
C++
1
file.read((char*)&im.name, sizeof(im.name));
то естественно, что не помогло
0
alsav22
5426 / 4821 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
10.03.2013, 17:31 #12
Проблема в том, что когда вы бинарно записываете в файл память под объектом string, то не понятно, что записывается (зависит от реализаци string). Может там указатель на строку, которая находится совсем в другом месте. Записали вы это указатель в файл. Потом считали его и пытаетесь через него что-то вывести. Отладчиком, ради интереса, посмотрите, что у вас в name перед выводом находится.
0
Croessmah
Ушел
Эксперт CЭксперт С++
13553 / 7704 / 872
Регистрация: 27.09.2012
Сообщений: 19,006
Записей в блоге: 3
Завершенные тесты: 1
10.03.2013, 17:34 #13
Цитата Сообщение от alsav22 Посмотреть сообщение
Потом считали его
Считали куда? Вникуда. Никто не выделял память под символы в im.name
0
Plu6e4ka
0 / 0 / 0
Регистрация: 05.11.2012
Сообщений: 18
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?
0
Croessmah
10.03.2013, 17:39     Работа с бинарными файлами (программка дважды записывает последнее число)
  #15

Не по теме:

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

1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.03.2013, 17:39
Привет! Вот еще темы с ответами:

Работа с бинарными файлами - C++
Помогите пожалуйста, уже перерыла все книги и весь инет, и чего-либо понятного мне не нашла..(( Мне нужно вывести на экранбинарный файл с...

Работа с бинарными файлами и структурами - C++
Всем привет. Да, есть похожие темы, но я ответа не нашел. В общем, у меня есть *.h файл в нем находиться класс #ifndef LOADING_H ...

Работа с текстовыми и бинарными файлами - C++
Дан файл вещественных чисел. Заменить в нем все элементы на их квадраты.

Работа с бинарными файлами и структурами - C++
Вылетает ошибка в методе Print. Может подскажите, а? Заранее спасибо! #ifndef CLASSLIBCARD_H #define CLASSLIBCARD_H #include...


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

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

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