Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.87/15: Рейтинг темы: голосов - 15, средняя оценка - 4.87
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
1

Считывание из файла

15.01.2020, 14:14. Показов 3041. Ответов 16
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Доброго!
Есть какие-то способы считывать 2 байта из файла в бинарном режиме и помещать их в одну переменную? К примеру: в char16_t или в int_16t.
А 4 байта считывать и в int или uint? Что происходит, если у меня файл на 3 байта, а я буду считывать int на 4 байта, как там избавляться от мусора из последнего байта?
Пытаюсь считать int, в файле одно число: 1
C++
1
2
3
4
5
ifstream is;
is.open(filepath, ios_base::in | ios_base::binary);
int a;
is.read((char*)&a, sizeof(a));
is.close();
Вывод:
Кликните здесь для просмотра всего текста
-858993615


Когда пытаюсь char16_t, файл тот же.
C++
1
2
char16_t buf;
is.read((char*)&buf, sizeof(char16_t));
Вывод
Кликните здесь для просмотра всего текста
52273


Придумал что-то такое:
C++
1
2
3
char buffer[2];
is.read((char*)&buffer, sizeof(char)*2);
cout << "output: " << buffer[0] << buffer[1] << "\n";
Вывод:
Кликните здесь для просмотра всего текста
1╠


По сути все правильно, 1 и мусор. Вот только это лежит в массиве. 2 элемента по 8 бит. А хочется в одном элементе на 16.
(да хоть на 32 в будущем)
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
15.01.2020, 14:14
Ответы с готовыми решениями:

Заменить считывание с клавиатуры на считывание из файла
Помогите пожалуйста, ни разу не работал со считыванием из файла поэтому не понимаю как и что...

Считывание файла в массив и запись нового файла
Консоль VS C++. Текстовый файл открывается как бинарный, и считывается по 100 байт в массив - и...

Считывание из файла
Доброго времени суток! Помогите с реализацией, есть файл столбец номера телефона и через табуляцию...

Считывание из файла
Помогите реализовать считывание символов из файла, в котором 10000 символов(0 и 1), двигаться...

16
369 / 312 / 65
Регистрация: 14.10.2014
Сообщений: 1,319
15.01.2020, 16:48 2
Battary, возможно то, что вам нужно вы найдёте здесь

Использование #pragma pack(push,1)... pack(pop)
0
43 / 39 / 5
Регистрация: 16.09.2019
Сообщений: 285
15.01.2020, 17:18 3
Цитата Сообщение от Battary Посмотреть сообщение
Что происходит, если у меня файл на 3 байта, а я буду считывать int на 4 байта, как там избавляться от мусора из последнего байта?
Позвольте полюбопытствовать, почему в файле оказалось 3 байта, если должно быть 4?
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
15.01.2020, 17:49  [ТС] 4
Цитата Сообщение от БедолагаЖека Посмотреть сообщение
Позвольте полюбопытствовать, почему в файле оказалось 3 байта, если должно быть 4?
Ну вот так вот исторически сложилось, в файле оказалось нечетное количество байт.
0
Фрилансер
3709 / 2082 / 567
Регистрация: 31.05.2009
Сообщений: 6,683
15.01.2020, 18:15 5
Ну обнулите старший байт руками
C++
1
2
int a = 0;
is.read((char*)&a, 3);
Добавлено через 4 минуты
Цитата Сообщение от Battary Посмотреть сообщение
Вывод 52273
Что-то Вы мудрите..
52273 = 0xcc31
У Вас в файле единица в символьном виде?
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
15.01.2020, 18:23  [ТС] 6
Цитата Сообщение от Black Fregat Посмотреть сообщение
Что-то Вы мудрите..
52273 = 0xcc31
У Вас в файле единица в символьном виде?
Да, файл просто состоит из 1
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
15.01.2020, 18:27 7
Цитата Сообщение от Battary Посмотреть сообщение
Есть какие-то способы считывать 2 байта из файла в бинарном режиме и помещать их в одну переменную?
C++
1
2
uint16_t val;
is.read((char *)&val, sizeof(val));
Цитата Сообщение от Battary Посмотреть сообщение
Что происходит, если у меня файл на 3 байта, а я буду считывать int на 4 байта
https://en.cppreference.com/w/... tream/read
Extracts characters from stream.

Behaves as UnformattedInputFunction. After constructing and checking the sentry object, extracts characters and stores them into successive locations of the character array whose first element is pointed to by s. Characters are extracted and stored until any of the following conditions occurs:
— count characters were extracted and stored
end of file condition occurs on the input sequence (in which case, setstate(failbit|eofbit) is called). The number of successfully extracted characters can be queried using gcount().
Цитата Сообщение от Battary Посмотреть сообщение
как там избавляться от мусора из последнего байта?
изначально занулять всю переменную, тогда несчитанный байт всегда будет 0.
1
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
15.01.2020, 21:27  [ТС] 8
Цитата Сообщение от GbaLog- Посмотреть сообщение
изначально занулять всю переменную, тогда несчитанный байт всегда будет 0.
Делаю копирование файла, но не побайтово(такое условие), если, сначала у меня был файл на 51 байт, а потом станет на 52 или 54, файл будет корректно работать или побьется?
0
43 / 39 / 5
Регистрация: 16.09.2019
Сообщений: 285
15.01.2020, 21:37 9
Цитата Сообщение от Battary Посмотреть сообщение
не побайтово(такое условие)
Это условие можно трактовать как в текстовом режиме(!!!), тогда вообще поехать сколько там байт

Добавлено через 2 минуты
Цитата Сообщение от Battary Посмотреть сообщение
файл будет корректно работать или побьется?
Нуль это тоже данные, если есть нуль - он запишется, даже если его не было, что бы этого не было копировать надо кратными размеру файла порциями, или как я написал выше...

Добавлено через 1 минуту
Кста! Никто не мешает скопировать ВЕСЬ файл разом!
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
15.01.2020, 21:47  [ТС] 10
Цитата Сообщение от БедолагаЖека Посмотреть сообщение
Кста! Никто не мешает скопировать ВЕСЬ файл разом!
Мешает. Условие: копирование файла в бинарном режиме, файл не должен копироваться побайтово(т.е. нельзя считать в char/другую переменную 1 байт и передать эту переменную на запись). То есть порции минимум по 16 бит. Файл может быть абсолютно любым, (txt/exe/bat/да хоть torrent).
0
43 / 39 / 5
Регистрация: 16.09.2019
Сообщений: 285
15.01.2020, 23:30 11

Не по теме:

Зуд в районе клоаки тебе мешает


Цитата Сообщение от Battary Посмотреть сообщение
То есть порции минимум по 16 бит.
ВЕСЬ СРАЗУ В ОДНУ ПЕРЕМЕННУЮ РАЗМЕРОМ С ФАЙЛ - пойдет такая порция?
0
Любитель чаепитий
3743 / 1799 / 566
Регистрация: 24.08.2014
Сообщений: 6,016
Записей в блоге: 1
16.01.2020, 05:25 12
Цитата Сообщение от Battary Посмотреть сообщение
Делаю копирование файла, но не побайтово(такое условие), если, сначала у меня был файл на 51 байт, а потом станет на 52 или 54, файл будет корректно работать или побьется?
тогда вам нужно проверить, сколько символов было извлечено на данной итерации, если вы достигли конца файла.
делается это просто:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <cstdint>
#include <iostream>
#include <sstream>
 
int main()
{
  std::istringstream is("\x11\x22\x33");
  uint32_t val;
  if (is.read((char *)&val, sizeof(val)).eof())
  {
    std::cout << "Stream has reached end of file, read count: " << is.gcount() << std::endl;
  }
}
как видите, я запихиваю в поток 3 символа(байта) и пытаюсь считать 4 байта, что не выходит, т.к. там всего 3.
это приводит к тому, что поток выставляет eofbit, который я проверяю в условии.
после чего вызываю gcount, чтобы узнать, сколько байт было записано до того, как был выставлен eofbit.
после этого я могу записать ровно столько байт, сколько считал и тогда файл не станет 52 или 54 байта.
1
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
16.01.2020, 11:05  [ТС] 13
Провел эксперимент на txt/jpg/mp3/exe файлах.
Все были нечетного количества байт. Считывал и записывал по 16 бит в бинарном режиме.
Было -> Стало
txt 27 26
jpg 710697 7106976
mp3 493553 493552
exe 4126497 4126496
При это все открывается и все работает, в txt явно потерялся последний байт, пропал символ, а в других файлах все хорошо.
Выходит потеря последнего байта не так страшна?

Добавлено через 11 минут
C++
1
2
3
4
5
6
7
8
9
char16_t ch;
        while (is.read((char*)&ch, sizeof(char16_t)))                                   
        {
            v.push_back(ch);
        }
        is.clear();                                                   //Пытаюсь сбросить флаги чтобы прочитать последний байт+мусор
        ch = NULL;                                                //Обнуляется контейнер до 00000000 00000000
        is.read((char*)&ch, sizeof(char16_t));         //Чтение из файла
        v.push_back(ch);
//Запись в хранилище
Но, увы не работает.
Как заставить программу прочитать последний байт и мусор потом?
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
16.01.2020, 11:45 14
Battary,
C++
1
2
3
4
5
6
7
8
9
    char chunk[ChunkSize]; // ChunkSize = 2 (16 bit)
    while (src.read(chunk, ChunkSize))
    {
        dst.write(chunk, ChunkSize);
    }
    if (std::streamsize gcnt = src.gcount())
    {
        dst.write(chunk, gcnt);
    }
0
43 / 39 / 5
Регистрация: 16.09.2019
Сообщений: 285
16.01.2020, 12:22 15
Цитата Сообщение от Battary Посмотреть сообщение
Выходит потеря последнего байта не так страшна?
На уровне фарта, лишь.... может оказаться принципиальной...
Так а в чем проблема переноса без потерь?
0
7 / 6 / 1
Регистрация: 29.10.2016
Сообщений: 175
16.01.2020, 12:44  [ТС] 16
Цитата Сообщение от БедолагаЖека Посмотреть сообщение
На уровне фарта, лишь.... может оказаться принципиальной...
Так а в чем проблема переноса без потерь?
Статистика, чтобы корректно велась, ещё дополнительно можно просмотреть какие комбинации char16_t встречались чаще всего. Естественно 8 бит тут никаким боком.
В идеале хотелось бы получить что-то для файлов, размер которых не кратен размеру контейнера.
Допустим у нас файл 5 байт, мы переносим его блоками по 2 байта, последний блок: [последний байт][eof]
Или переносим блоками по 4 байта, тогда последний блок: [последний байт][eof][eof][eof].
Т.е. просто добивать eof-ми, все-равно вся информация после eof игнорируется.
0
19409 / 10028 / 2443
Регистрация: 30.01.2014
Сообщений: 17,678
16.01.2020, 13:10 17
Цитата Сообщение от Battary Посмотреть сообщение
идеале хотелось бы получить что-то для файлов, размер которых не кратен размеру контейнера.
Допустим у нас файл 5 байт, мы переносим его блоками по 2 байта, последний блок: [последний байт][eof]
Или переносим блоками по 4 байта, тогда последний блок: [последний байт][eof][eof][eof].
Т.е. просто добивать eof-ми, все-равно вся информация после eof игнорируется.
Символ EOF (байт со значением 0x04) в бинарном файле может быть где угодно.
Тот eof, который вам возвращает поток - это состояние потока, а не конкретный символ из файла.
0
16.01.2020, 13:10
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.01.2020, 13:10
Помогаю со студенческими работами здесь

Считывание с файла
#Oblast1 g;ergtr hwtrh rt h trh ert h hry e #Oblast2 oooooooqwe qweeeeeeeeee qweeeeeeeee...

Считывание из файла
//считываем данные об услугах из файла in.open(&quot;ресурсы.txt&quot;); while(!in.eof()) ...

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

Считывание из файла
Помогите пожалуйста! Почему не работает? Нужно считать из файла в двумерный массив матрицу...


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

Или воспользуйтесь поиском по форуму:
17
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru