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

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

Войти
Регистрация
Восстановить пароль
 
andreyananas
22 / 22 / 9
Регистрация: 15.10.2013
Сообщений: 862
Завершенные тесты: 2
#1

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

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

Неправильно читает двоичный файл - C++
#include &lt;iostream&gt; #include &lt;locale.h&gt; using namespace std; /*14.Информационная система «Детали и изделия». Цех на предприятии ...

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

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

не читает файл - C++
Проблема такова: пытаюсь открыть текстовый файл,код точно правильный,т.к работает на другом компьютере,но у меня выдает пустой экран.в...

Не читает файл _wfopen_s - C++
Пишу программу которая удалит из папки songs все файлы с расширением .osu у которых в 10 строчке в стоит mode: 1. Прога ищет все файлы с...

Программа не читает файл - C++
Программа не читает файл. Подскажите, где моя ошибка. // lab7.cpp: определяет точку входа для консольного приложения. // #include...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
ThePlague
101 / 101 / 61
Регистрация: 30.06.2015
Сообщений: 272
27.01.2016, 14:25 #2
andreyananas, 22 строка *10 забыли!

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

C++
1
while(fin.getline((char*)pAr,0));
nord_v
227 / 176 / 69
Регистрация: 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));
Не можно. Бинарно записаны инты, а ты собираешься читать их строковой функцией?
ThePlague
101 / 101 / 61
Регистрация: 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;
}
nord_v
227 / 176 / 69
Регистрация: 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;
ThePlague
101 / 101 / 61
Регистрация: 30.06.2015
Сообщений: 272
27.01.2016, 15:53 #9
nord_v, каюсь, поспешил...
andreyananas
22 / 22 / 9
Регистрация: 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;
}
Спасибо за направление (глупая ошибка была).

Но все это действительно только когда знаешь размер массива.
А как измерить размер файла? (Вариант записать первым значением инт с размером следующего массива -- не годиться).
AlexVRud
442 / 152 / 38
Регистрация: 04.07.2014
Сообщений: 431
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
22 / 22 / 9
Регистрация: 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;
?
AlexVRud
442 / 152 / 38
Регистрация: 04.07.2014
Сообщений: 431
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 случайными числами.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.01.2016, 14:49
Привет! Вот еще темы с ответами:

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

ifstream читает файл со второй строки - C++
Добрый день, читаю файл через fstream и записываю его, запись идет только со второй строки, не могу понять почему #include &lt;iostream&gt; ...

При занесении данных с консоли в файл не читает кириллицу - C++
Добрый вечер. Такая проблема:при занесении данных с консоли в файл не читает кириллицу,если данные в консоли ввожу на латинице,то все...

Вторая программа не читает файл, созданный первой программой - C++
int main() { setlocale( LC_ALL,&quot;Russian&quot; ); FILE *f; int i; const int N=4; int ch={9,13,2,4}; i=0; if...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
28.01.2016, 14:49
Ответ Создать тему
Опции темы

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