Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/5: Рейтинг темы: голосов - 5, средняя оценка - 5.00
andreyananas
22 / 22 / 11
Регистрация: 15.10.2013
Сообщений: 862
Завершенные тесты: 2
1

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

27.01.2016, 13:59. Просмотров 1013. Ответов 12
Метки нет (Все метки)

Вот код программы (суть в тесте методов С++ по работе с бинарными файлами):
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;
}
То есть заполняем файл массивом и далее читаем его с файла.
Но первый элемент в массиве не совпадает! ПОЧЕМУ?
0
Миниатюры
Неправильно читает файл  
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.01.2016, 13:59
Ответы с готовыми решениями:

Неправильно читает двоичный файл
#include &lt;iostream&gt; #include &lt;locale.h&gt; using namespace std;...

Неправильно читает данные из файла
Ситуация следующая. Выполняю ввод данных(фамилия и возраст), затем они...

не читает файл в Qt
дан фрагмент программы, которая должна читать сведения из текстового файла, но...

не читает файл
Проблема такова: пытаюсь открыть текстовый файл,код точно правильный,т.к...

Не читает файл _wfopen_s
Пишу программу которая удалит из папки songs все файлы с расширением .osu у...

12
ThePlague
102 / 102 / 99
Регистрация: 30.06.2015
Сообщений: 272
27.01.2016, 14:25 2
andreyananas, 22 строка *10 забыли!

C++
1
while (fin.read((char*)pAr, sizeof(int)*10));
0
andreyananas
22 / 22 / 11
Регистрация: 15.10.2013
Сообщений: 862
Завершенные тесты: 2
27.01.2016, 14:40  [ТС] 3
Цитата Сообщение от ThePlague Посмотреть сообщение
22 строка *10 забыли!
Ну типа размер массива не известен.
0
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
27.01.2016, 15:38 4
Цитата Сообщение от andreyananas Посмотреть сообщение
Ну типа размер массива не известен.
Читаешь по одному int, всегда в первый элемент массива, затирая предыдущее чтение. Последняя 4-ка из файла и остаётся.
1
ThePlague
102 / 102 / 99
Регистрация: 30.06.2015
Сообщений: 272
27.01.2016, 15:38 5
andreyananas, можно еще так:

C++
1
while(fin.getline((char*)pAr,0));
0
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
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));
Не можно. Бинарно записаны инты, а ты собираешься читать их строковой функцией?
1
ThePlague
102 / 102 / 99
Регистрация: 30.06.2015
Сообщений: 272
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;
}
0
nord_v
329 / 177 / 80
Регистрация: 22.08.2013
Сообщений: 724
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;
3
ThePlague
102 / 102 / 99
Регистрация: 30.06.2015
Сообщений: 272
27.01.2016, 15:53 9
nord_v, каюсь, поспешил...
0
andreyananas
22 / 22 / 11
Регистрация: 15.10.2013
Сообщений: 862
Завершенные тесты: 2
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;
}
Спасибо за направление (глупая ошибка была).

Но все это действительно только когда знаешь размер массива.
А как измерить размер файла? (Вариант записать первым значением инт с размером следующего массива -- не годиться).
0
AlexVRud
479 / 191 / 72
Регистрация: 04.07.2014
Сообщений: 538
28.01.2016, 12:46 11
Лучший ответ Сообщение было отмечено andreyananas как решение

Решение

  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;
}
1
andreyananas
22 / 22 / 11
Регистрация: 15.10.2013
Сообщений: 862
Завершенные тесты: 2
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;
?
0
AlexVRud
479 / 191 / 72
Регистрация: 04.07.2014
Сообщений: 538
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 случайными числами.
1
28.01.2016, 14:49
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2016, 14:49

Программа не читает файл
Программа не читает файл. Подскажите, где моя ошибка. // lab7.cpp: определяет...

Читает не весь текстовый файл
Необходимо написать программу, которая создаёт файл ключей, потом по этому...

ifstream читает файл со второй строки
Добрый день, читаю файл через fstream и записываю его, запись идет только со...


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

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

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