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

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

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 93, средняя оценка - 4.70
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
#1

Запись/чтение массива структур в бинарный файл - C++

11.01.2013, 10:50. Просмотров 15248. Ответов 22
Метки нет (Все метки)

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
#include <iostream>
#include <fstream>
 
using namespace std;
 
struct test 
{ 
    int x; 
    int y;  
}; 
 
int main() 
{       
    int size = 5;
  
    test arr[size];
    test tmp; 
 
    for(int i = 0; i < size; ++i)
    {    
        cout << "Enter x: ";
        cin >> arr[i].x; 
        cout << "Enter y: ";
        cin >> arr[i].y;    
        cout << "\n";
    }  
 
    // запись массива в файл
    ofstream fout("data.dat", ios::binary); 
    for(int i = 0; i < size; ++i) 
    {      
        fout.write(reinterpret_cast<char*>(&arr[i]), sizeof(test));
    }
    fout.close();
    
    // чтение из файла одной записи
    ifstream fin("data.dat", ios::binary); 
    fin.seekg(-3 * sizeof(tmp), ios::end);
    fin.read(reinterpret_cast<char*>(&tmp), sizeof(test));
    cout << "x: " << tmp.x << " y: " << tmp.y << "\n";
    
    fin.close();
 
    return 0;
}
Создаю массив структур, записываю в бинарный файл. Некорректно происходит считывание записи с конца файла. То есть при установке позиции таким образом:
C++
1
fin.seekg(-3 * sizeof(tmp), ios::end);
и последующем чтении
C++
1
fin.read(reinterpret_cast<char*>(&tmp), sizeof(test));
в tmp оказывается мусор (вернее вовсе не меняются ее элементы, это видно, если были присвоены какие-то значения ранее). При чтении с начала файла такой проблемы нет:
C++
1
fin.seekg(2 * sizeof(tmp), ios::beg);
Что я делаю не так?
0
Миниатюры
Запись/чтение массива структур в бинарный файл  
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.01.2013, 10:50
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Запись/чтение массива структур в бинарный файл (C++):

Запись в бинарный файл и чтение из него массива структур - C++
Ребята, выручайте. Огромная проблема с записью и с чтением структуры из бинарного файла. Помогите кто чем может. void bin_w() { int...

Запись в бинарный файл и чтение из него массива структур - C++
Здравствуйте, появилась проблема записью структуры в бинарный файл и чтение из него этой же структуры. Я находил код с записью char, но я...

Запись массива структур в бинарный файл - C++
Одно из полей структуры типа String, нужно записать массив структур в бинарный файл: struct NOTEBOOK { string model; // наименование ...

Запись массива структур в бинарный файл - C++
Есть структура Owner: struct Owner{ char name; unsigned int purse; short catb; void addcat(short num); }; ...

Запись и чтение в файл массива структур в которую вложен вектор - C++
Здравствуйте! Подскажите как и можно ли вообще записать в один файл данную структуру: struct Xozorgan { char familia; char...

Считывание и запись структур в бинарный файл - C++
Здравствуйте, я делаю автоподгрузку и авто сохранение некоторой структуры в бинарный файл. И где-то допустил грубую ошибку, ибо...

22
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
11.01.2013, 17:18  [ТС] #16
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Так тоже ss.seekg(-48, ios::end);
Почему 48? ss.seekg(-24, ios::end); - это то ест нормально)
http://codepad.org/VCaAwxdO
0
-=ЮрА=-
Заблокирован
Автор FAQ
11.01.2013, 17:40 #17
Schizorb, в seekg идёт преобразование типа к беззнаковому
http://codepad.org/M9WwMxMo вот смотри что там написано
cc1plus: warnings being treated as errors
Line 44: warning: this decimal constant is unsigned only in ISO C90
а раз unsigned only то юзать -3 некорректно а отработка с -3 и signed скорее баг нежели правильная отработка - лучше двигаться от начала это 100% будет однозначный результат и главное в стандарте.

Добавлено через 11 минут

Не по теме:

Вот однозначный ответ http://codepad.org/BMhFu1eh -24 преобразуется в unsigned и выходит внутрь seekg передаётся 4294967272 что само по себе странно!



Добавлено через 4 минуты
При этом запихнуть туда 4294967272 явным способом невозможно http://codepad.org/LFBwWQ24. Лично я считаю такое положение вещей багом а не достоинством стандарта
1
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
11.01.2013, 17:42  [ТС] #18
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
с signed идёт преобразование типа к беззнаковому. Вот смотри что там написано
Хм, предупреждение тут по-моему из-за того, что 4294967272 - слишком большой литерал для типа signed int, а не потому, что типы параметра и аргумента для seekg не совпадают. То есть, вот так, скомпилируется без предупреждения.

C++
1
ss.seekg(4294967272U, ios::end);
Результат, конечно, будет неправильный, в том плане, что отрицательного сдвига никакого не будет (кстати, а студия что скажет на сдвиг 4294967272U ?).

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
а отработка с -3 и signed скорее баг нежели правильная отработка
С signed-то без проблем работает, и на разных компиляторах. Вот почему на Visual Stusio у вас отработало с -3 * sizeof(test), чей результат unsigned, это видимо особенности студийного компилятора.
0
-=ЮрА=-
Заблокирован
Автор FAQ
11.01.2013, 17:47 #19
Цитата Сообщение от Schizorb Посмотреть сообщение
это видимо особенности студийного компилятора.
Я писал что студия стоит особняком от стандарта
Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Я потому и удивился что -3 в студии отработало. Она то ведь вне стандарта.
Продолжу настаивать на том что следует двигать курсор от начала это будет однозначно и понятно на любом компиляторе.

Добавлено через 1 минуту
Цитата Сообщение от Schizorb Посмотреть сообщение
Результат, конечно, будет неправильный, в том плане, что отрицательного сдвига никакого не будет (кстати, а студия что скажет на сдвиг 4294967272U ?).
- сейчас глянем
0
-=ЮрА=-
Заблокирован
Автор FAQ
11.01.2013, 17:51 #20
Вот студийная отработка
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
#include <iostream>
#include <sstream>
 
using namespace std;
 
struct test 
{ 
    int x; 
    int y;  
}; 
 
int main() 
{       
    int i;
    const int size = 5;
  
    test arr[size];
    test tmp; 
 
    cout<<           sizeof(tmp)<<endl;
    cout<<-3*        sizeof(tmp)<<endl;
    cout<<-3*(signed)sizeof(tmp)<<endl;
 
    for(i = 0; i < size; ++i)
    {    
        cout << "Enter x: "<<(arr[i].x = i)<<endl;
        //cin >> arr[i].x; 
        cout << "Enter y: "<<(arr[i].y = i)<<endl;
        //cin >> arr[i].y;    
        cout << "\n";
    }  
 
    // Г§Г*ГЇГЁГ±Гј Г¬Г*Г±Г±ГЁГўГ* Гў ГґГ*éë
    stringstream ss; 
    for(i = 0; i < size; ++i) 
    {      
        ss.write(reinterpret_cast<char*>(&arr[i]), sizeof(test));
    }
    ss.clear();
    ss.seekg(0, ios::beg);
    
    // Г·ГІГҐГ*ГЁГҐ ГЁГ§ ГґГ*éëГ* îäГ*îé Г§Г*ГЇГЁГ±ГЁ 
    unsigned int pos = 4294967272;
    cout<<pos<<endl;
    ss.seekg(/*-3 * sizeof(tmp)*/pos, ios::end);
    ss.read(reinterpret_cast<char*>(&tmp), sizeof(test));
    cout << "x: " << tmp.x << " y: " << tmp.y << "\n";
 
    ss.seekg(/*-3 * sizeof(tmp)*/4294967272, ios::end);
    ss.read(reinterpret_cast<char*>(&tmp), sizeof(test));
    cout << "x: " << tmp.x << " y: " << tmp.y << "\n";
 
    ss.clear();
    ss.seekg(2 * sizeof(tmp), ios::beg);
    ss.read(reinterpret_cast<char*>(&tmp), sizeof(test));
    cout << "x: " << tmp.x << " y: " << tmp.y << "\n";
    
    
 
    return 0;
}
1
Миниатюры
Запись/чтение массива структур в бинарный файл  
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
11.01.2013, 18:02  [ТС] #21

Не по теме:

Цитата Сообщение от -=ЮрА=- Посмотреть сообщение
Вот студийная отработка
да, спасибо, не сомневался что в студии так и будет.



Добавлено через 9 минут
Кстати говоря, первый параметр перегруженной функции seekg имеет другой тип - streamoff, а не streampos

istream& seekg ( streampos pos );
istream& seekg ( streamoff off, ios_base::seekdir dir );
0
WhiteP
606 / 204 / 23
Регистрация: 20.11.2012
Сообщений: 426
11.01.2013, 18:09 #22
Schizorb,
вот, тут и видел про signed
http://en.cppreference.com/w/cpp/io/streamoff
1
Schizorb
510 / 462 / 16
Регистрация: 07.04.2012
Сообщений: 865
Записей в блоге: 1
Завершенные тесты: 1
11.01.2013, 18:30  [ТС] #23
WhiteP, спасибо!

Исходя из того, что "typically, this is a typedef to long long", можно и увидеть на сколько позиций я пытался сдвигаться и как это сделать правильно.

C++
1
2
3
4
5
6
7
8
9
10
11
12
// положительное смещение
long long int x = 3 * sizeof(test);
    
// отрицательное смещение (неправильное)
long long int y = -3 * sizeof(test);
    
// отрицательное смещение
long long int z = -3 * signed(sizeof(test));
    
cout << x << endl;
cout << y << endl;
cout << z << endl;
А в студии 6.0, видимо, этот тип представлен просто long, вот и получается, как на скриншоте.
0
Миниатюры
Запись/чтение массива структур в бинарный файл  
11.01.2013, 18:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
11.01.2013, 18:30
Привет! Вот еще темы с ответами:

Чтение и запись в бинарный файл - C++
Ребят nомогите мне nожалуйста. Я хочу nрочитать бинарный файл , в котором заnисаны данные в виде структуры, глянул в инете как читают и...

Чтение и запись в бинарный файл - C++
Добрый день! Помогите разобраться. Надо записать информацию в бинарник, а потом прочесть из него и вывести на экран. Вроде все делаю...

Чтение/Запись в текстовый и бинарный файл. - C++
Подскажите в чем ошибка. Функции чтения и записи в бинарный и текстовый файл толком не работают( Вот программа: HEADER.H ...

Запись в бинарный файл и чтение из него - C++
Нужно записать в бинарный файл блоки, каждый по 512 байт. Структура блока: Слово Число. На слово отводится 508 байт, на число 4. После...


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

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

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