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

Неправильно читает файл - C++

Восстановить пароль Регистрация
 
andreyananas
 Аватар для andreyananas
17 / 17 / 5
Регистрация: 15.10.2013
Сообщений: 806
27.01.2016, 13:59     Неправильно читает файл #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
26
27
28
29
30
31
#include "stdafx.h"
#include <iostream>
#include <fstream>
 
 
using namespace std;
 
int main()
{
    int * pAr = new int[10];
    for (int i(0); i < 10; ++i)
        pAr[i] = rand() % 10;
    for (int i(0); i < 10; ++i)
        cout << pAr[i] << ' ';
    cout << endl;
 
    ofstream fout("1.dat", ios_base::out | ios_base::binary);
    fout.write((char*)pAr, sizeof(int)*10);
    fout.close();
 
    ifstream fin("1.dat", ios_base::in | ios_base::binary);
    while (fin.read((char*)pAr, sizeof(int)));
    fin.close();
 
    for (int i(0); i < 10; ++i)
        cout << pAr[i] << ' ';
    cout << endl;
 
    delete[] pAr;
    return 0;
}
То есть заполняем файл массивом и далее читаем его с файла.
Но первый элемент в массиве не совпадает! ПОЧЕМУ?
Миниатюры
Неправильно читает файл  
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.01.2016, 13:59     Неправильно читает файл
Посмотрите здесь:

C++ не читает файл
ifstream читает файл со второй строки C++
C++ Неправильно читает данные из файла
C++ не читает файл в Qt
Программа не читает файл C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
ThePlague
 Аватар для ThePlague
95 / 95 / 59
Регистрация: 30.06.2015
Сообщений: 262
27.01.2016, 14:25     Неправильно читает файл #2
andreyananas, 22 строка *10 забыли!

C++
1
while (fin.read((char*)pAr, sizeof(int)*10));
andreyananas
 Аватар для andreyananas
17 / 17 / 5
Регистрация: 15.10.2013
Сообщений: 806
27.01.2016, 14:40  [ТС]     Неправильно читает файл #3
Цитата Сообщение от ThePlague Посмотреть сообщение
22 строка *10 забыли!
Ну типа размер массива не известен.
nord_v
227 / 176 / 69
Регистрация: 22.08.2013
Сообщений: 723
27.01.2016, 15:38     Неправильно читает файл #4
Цитата Сообщение от andreyananas Посмотреть сообщение
Ну типа размер массива не известен.
Читаешь по одному int, всегда в первый элемент массива, затирая предыдущее чтение. Последняя 4-ка из файла и остаётся.
ThePlague
 Аватар для ThePlague
95 / 95 / 59
Регистрация: 30.06.2015
Сообщений: 262
27.01.2016, 15:38     Неправильно читает файл #5
andreyananas, можно еще так:

C++
1
while(fin.getline((char*)pAr,0));
nord_v
227 / 176 / 69
Регистрация: 22.08.2013
Сообщений: 723
27.01.2016, 15:42     Неправильно читает файл #6
C++
1
2
3
    int* p = pAr;
    while (fin.read((char*)p, sizeof(int)))
    { ++p; }
Добавлено через 1 минуту
Цитата Сообщение от ThePlague Посмотреть сообщение
можно еще так:
C++
1
while(fin.getline((char*)pAr,0));
Не можно. Бинарно записаны инты, а ты собираешься читать их строковой функцией?
ThePlague
 Аватар для ThePlague
95 / 95 / 59
Регистрация: 30.06.2015
Сообщений: 262
27.01.2016, 15:43     Неправильно читает файл #7
nord_v, ну мне не веришь просто попробуй!

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
#include <iostream>
#include <fstream>
 
 
using namespace std;
 
int main()
{
    int * pAr = new int[10];
    for (int i(0); i < 10; ++i)
        pAr[i] = rand() % 10;
    for (int i(0); i < 10; ++i)
        cout << pAr[i] << ' ';
    cout << endl;
 
    ofstream fout("1.dat", ios_base::out | ios_base::binary);
    fout.write((char*)pAr, sizeof(int)*10);
    fout.close();
 
    ifstream fin("1.dat", ios_base::in | ios_base::binary);
    while(fin.getline((char*)pAr,0));
    fin.close();
 
    for (int i(0); i < 10; ++i)
        cout << pAr[i] << ' ';
    cout << endl;
 
    delete[] pAr;
    return 0;
}
nord_v
227 / 176 / 69
Регистрация: 22.08.2013
Сообщений: 723
27.01.2016, 15:48     Неправильно читает файл #8
Цитата Сообщение от andreyananas Посмотреть сообщение
Ну типа размер массива не известен.
Если неизвестен, то по-другому делается: сначала вычисляется размер данных в файле, выделяется нужная память, потом чтение.

Добавлено через 3 минуты
Цитата Сообщение от ThePlague Посмотреть сообщение
ну мне не веришь просто попробуй!
А чтение у тебя там есть, вообще? Старый массив выводит. Вот так попробуй и посмотри:
C++
1
2
3
4
5
6
7
8
9
10
    ifstream fin("1.dat", ios_base::in | ios_base::binary);
    
    int * pAr2 = new int[10];
    while (fin.getline((char*)pAr2, 0));
    
    fin.close();
 
    for (int i(0); i < 10; ++i)
        cout << pAr2[i] << ' ';
    cout << endl;
ThePlague
 Аватар для ThePlague
95 / 95 / 59
Регистрация: 30.06.2015
Сообщений: 262
27.01.2016, 15:53     Неправильно читает файл #9
nord_v, каюсь, поспешил...
andreyananas
 Аватар для andreyananas
17 / 17 / 5
Регистрация: 15.10.2013
Сообщений: 806
28.01.2016, 11:31  [ТС]     Неправильно читает файл #10
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
// test_readADNwrite_FILE.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <memory>
 
using namespace std;
 
 
int main()
{
    int nSize(10);
    int * pAr = new int[nSize];
    for (int i(0); i < nSize; ++i)
    {
        pAr[i] = rand() % 100;
        cout << pAr[i] << ' ';
    }
    cout << endl;
 
    string path = "1.dat";
    ofstream fout;
    fout.open(path.c_str(), ios_base::out | ios_base::binary);
    fout.write((char*)pAr, sizeof(int)*nSize);
    fout.close();
 
    ifstream fin;
    fin.open(path.c_str(), ios_base::in | ios_base::binary);
    int * pBuff = new int[nSize];
    int * pCur = pBuff;
    int SizeBuff(0);
    while (fin.read((char*)pCur++, sizeof(int)))
        SizeBuff++;
 
 
    for (int i(0); i < SizeBuff; ++i)
        cout << pBuff[i] << ' ';
    cout << endl;
 
 
    delete[] pBuff;
    delete[] pAr;
    return 0;
}
Спасибо за направление (глупая ошибка была).

Но все это действительно только когда знаешь размер массива.
А как измерить размер файла? (Вариант записать первым значением инт с размером следующего массива -- не годиться).
AlexVRud
414 / 143 / 36
Регистрация: 04.07.2014
Сообщений: 415
28.01.2016, 12:46     Неправильно читает файл #11
Сообщение было отмечено автором темы, экспертом или модератором как ответ
  1. Используй std::vector, не надо будет следить за освобождением памяти.
  2. rand уже давно объявлен устаревшим, возможно объявление генератора случайных чисел из С++11 и занимает несколько строк, но зато он лишён большой части проблем присущих rand, более гибок и корректен.
  3. Для определения размера файла используй seek.
  4. Пользуйся плюшками от новых стандартов С++.

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
#include <iostream>
#include <fstream>
#include <memory>
#include <vector>
#include <random>
#include <algorithm>
#include <iterator>
 
int main()
{
  std::string file_path = "1.dat";
 
  {
    const size_t xs_size = 10;
    std::vector<int64_t> xs(xs_size);
 
    std::random_device rand_dev;
    std::mt19937 rand_engine(rand_dev());
    std::uniform_int_distribution<int64_t> rand_dis(10, 99);
    auto rand_generator = std::bind(rand_dis, rand_engine);
 
    std::generate(xs.begin(), xs.end(), rand_generator); 
 
    for(auto &e: xs) {
      std::cout << e << ' ';
    }
    std::cout << "\n";
 
    std::ofstream fout;
    fout.open(file_path, std::ios_base::out | std::ios_base::binary);
    fout.write(reinterpret_cast<const char *>(xs.data()), sizeof(int64_t)*xs.size());
    fout.close();
  }
 
  {
    std::vector<int64_t> ys;
 
    std::ifstream fin;
    fin.open(file_path, std::ios_base::in | std::ios_base::binary);
 
    fin.seekg(0, fin.end);
    size_t file_size = fin.tellg();
    fin.seekg(0);
 
    ys = std::vector<int64_t>(file_size / sizeof(int64_t));
 
    fin.read(reinterpret_cast<char *>(ys.data()), sizeof(int64_t)*ys.size());
 
    std::copy(ys.begin(), ys.end()-1, std::ostream_iterator<int64_t>(std::cout, " "));
    std::cout << ys.back() << std::endl;
 
  }
 
  return 0;
}
andreyananas
 Аватар для andreyananas
17 / 17 / 5
Регистрация: 15.10.2013
Сообщений: 806
28.01.2016, 14:06  [ТС]     Неправильно читает файл #12
Цитата Сообщение от AlexVRud Посмотреть сообщение
C++
1
2
3
fin.seekg(0, fin.end);
size_t file_size = fin.tellg();
fin.seekg(0);
Логично=) Спасибо.
Цитата Сообщение от AlexVRud Посмотреть сообщение
C++
1
2
3
4
5
std::random_device rand_dev;
std::mt19937 rand_engine(rand_dev());
std::uniform_int_distribution<int64_t> rand_dis(10, 99);
auto rand_generator = std::bind(rand_dis, rand_engine);
std::generate(xs.begin(), xs.end(), rand_generator);
Это все вместо
C++
1
rand()%10;
?
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2016, 14:49     Неправильно читает файл
Еще ссылки по теме:

C++ Вторая программа не читает файл, созданный первой программой
Читает не весь текстовый файл C++
C++ Неправильно читает двоичный файл

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

Или воспользуйтесь поиском по форуму:
AlexVRud
414 / 143 / 36
Регистрация: 04.07.2014
Сообщений: 415
28.01.2016, 14:49     Неправильно читает файл #13
Нет.

C++
1
2
3
4
std::random_device rand_dev;
std::mt19937 rand_engine(rand_dev());
std::uniform_int_distribution<int64_t> rand_dis(10, 99);
auto rand_generator = std::bind(rand_dis, rand_engine);
создаст и инициализирует новый объект с методом operator(), который будет выдавать равномерно распределённые случайные числа из интервала [10,99]. И тогда вместо 10+rand()%90 ты можешь использовать rand_generator(). При этом он заменит ещё и srand. Кроме этого rand()%n не даёт равномерного распределения на интервале [0,n-1], где-то будет больше, где-то меньше, а какие-то числа он никогда не выдаст.

C++
1
std::generate(xs.begin(), xs.end(), rand_generator);
- это заполнение вектора xs случайными числами.
Yandex
Объявления
28.01.2016, 14:49     Неправильно читает файл
Ответ Создать тему
Опции темы

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