Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Считать файл в бинарном виде, Считать без хитровыеманых ухищрений 
:(
    Опции темы
cupper
Дата 24.3.2009, 20:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



О ужас, нету на форуме темы где было бы нормально написано это,  куча тем с похожим вопросом и немеренная куча вариантов как якобы это делаеться, но в итоге нече неработает. 

Нужно считать бинарный файл, вот его спецификация
TEST SET LABEL FILE (t10k-labels-idx1-ubyte):
[offset] [type]          [value]          [description] 
0000     32 bit integer  0x00000801(2049) magic number (MSB first) 
0004     32 bit integer  10000            number of items 
0008     unsigned byte   ??               label 
0009     unsigned byte   ??               label 
........ 
xxxx     unsigned byte   ??               label 

The labels values are 0 to 9.
http://yann.lecun.com/exdb/mnist/index.html - первоисточник

вот как я пытался делать, точнее последний вариант который хоть чтото делал
Скрытый текст

Код

#include <iostream>
#include <fstream>

using namespace std;

int main (){
    ifstream file("t10k-labels.idx1-ubyte", ios::in | ios::binary);
    unsigned int bit_magic_number, bit_number_of_items;
    bit_magic_number = 666; bit_number_of_items = 999;
    //file>>bit_magic_number>>bit_number_of_items;
    file.read((char*)&bit_magic_number, sizeof(bit_magic_number));
    file.read((char*)&bit_number_of_items, sizeof(bit_number_of_items));
    unsigned char array[10];
    for (int i=0; i<10; i++)    file>>array[i];
    file.close();
    cout<<"bit_magic_number ="<<bit_magic_number<<endl;
    cout<<"bit_number_of_items ="<<bit_number_of_items<<endl;
    for (int i=0; i<10; i++){
        cout<<int(array[i])<<endl;
    }
    char a;
    cin>>a;
}


выводит следующее
Код

bit_magic_number =17301504
bit_number_of_items =270991360
7
2
1
0
4
1
4
5
0
6

Вот началные биты 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x27, 0x10, это какраз числа 2049 и 10000.
что несоотвествует спецификации. Помогите плиз. 
Язык С++, некаких С-функций, использем fstream.

Добавлено через 9 минут и 3 секунды
вот дерьмо, 17301504 этож как раз если в битах 01 08 00 00, в точности наоборот. Эта даже понятно почему так, но как сделать чтобы читалось в том виде в каком надо

Это сообщение отредактировал(а) cupper - 24.3.2009, 20:24
PM MAIL   Вверх
Friackazoid
Дата 24.3.2009, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 148
Регистрация: 23.2.2006

Репутация: нет
Всего: 3



ГОСПОДИ...  smile зачем такой сложный код-то

Код

int main () {
   FILE* file;
   int magic, number;
   char picture[size];

   file = fopen ("filename", "r");

    fscanf (file, "%i%i", &magic, &number);

    do {
       picture[i] = fgetc (file);
    } while (i<size && picture[i] != magic)
      

}

--------------------
Даже если тебя съели, то все равно есть два выхода.42Team блог
PM MAIL WWW ICQ GTalk   Вверх
cupper
Дата 24.3.2009, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



после небольшое шлефошки на техже данных выдает
magic = 2293672
number = 2088810083
0 0 8 1 0 0 39 16 7 2
что я хз как обяснить, пока. 
Вопрос в силе.

------
1) пока этот код вообще нече нечитает, а значения случайный мусор
2) ...

------

необязательно только на С++, С тоже уместно теперь. Любыми фукнциями, лижбы балы решена поставленная задача... я в отчаяние ((

Это сообщение отредактировал(а) cupper - 24.3.2009, 23:17
PM MAIL   Вверх
jonie
Дата 25.3.2009, 07:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



какая у вас платформа? Подозреваю что littleendian. Используйте сетевые функции для переворачивания байтов в обратный порядок. 
Цитата

Функция htonl осуществляет перевод целого длинного числа из порядка байт, принятого на компьютере, в сетевой порядок байт. 

Функция htons осуществляет перевод целого короткого числа из порядка байт, принятого на компьютере, в сетевой порядок байт. 

Функция ntohl осуществляет перевод целого длинного числа из сетевого порядка байт в порядок байт, принятый на компьютере. 

Функция ntohs осуществляет перевод целого короткого числа из сетевого порядка байт в порядок байт, принятый на компьютере.



--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
cupper
Дата 25.3.2009, 11:22 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



ну к примеру считал я первые два значения int , дальше идут unsigned byte, тобишь char, считываю их в миссив чар, при выводу конвертируя их в int получаю значения в диапазоне от -127 до 128. Мне же нужно чтобы было от 0 до 255, исли конвертировать в unsigned то вместо отрицательных выводяться очень большие числа. Я конечно могу проста при конфертировании в int прибовлять к полученному значению 127 тем самым получив нужный диапазон, НО это УЖАС !!!
как еще можно ?
Значения это диапазон цветов от 0 (белый) до 255 (чертный)

а функции ntohs и т.д. в какои библиотеке ? в мсдн написано что Winsock2.h, но это ж сугубо виндовская, а какже для линукса ?
PM MAIL   Вверх
mes
Дата 25.3.2009, 12:12 (ссылка)   | (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(cupper @  25.3.2009,  10:22 Найти цитируемый пост)
не же нужно чтобы было от 0 до 255, исли конвертировать в unsigned то вместо отрицательных выводяться очень большие числа. как еще можно ? 

Код

  unsigned int sch2uint (signed char c) { return static_cast<unsigned int>(static_cast<unsigned char>(c)); }

  char c = -4;
  std::cout << sch2uint(c);




--------------------
PM MAIL WWW   Вверх
cupper
Дата 25.3.2009, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(jonie @ 25.3.2009,  07:57)
какая у вас платформа? Подозреваю что littleendian. Используйте сетевые функции для переворачивания байтов в обратный порядок. 
Цитата

Функция htonl осуществляет перевод целого длинного числа из порядка байт, принятого на компьютере, в сетевой порядок байт. 

Функция htons осуществляет перевод целого короткого числа из порядка байт, принятого на компьютере, в сетевой порядок байт. 

Функция ntohl осуществляет перевод целого длинного числа из сетевого порядка байт в порядок байт, принятый на компьютере. 

Функция ntohs осуществляет перевод целого короткого числа из сетевого порядка байт в порядок байт, принятый на компьютере.

эм что за платформа ? непонял.
На функцию компилятор выдает непонятную ошибку, 
  [Linker error] undefined reference to `ntohl@4' 
при передачи в качестве параметра переменной insigned int
PM MAIL   Вверх
cupper
Дата 25.3.2009, 21:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



Цитата(mes @ 25.3.2009,  12:12)
Цитата(cupper @  25.3.2009,  10:22 Найти цитируемый пост)
не же нужно чтобы было от 0 до 255, исли конвертировать в unsigned то вместо отрицательных выводяться очень большие числа. как еще можно ? 

Код

  unsigned int sch2uint (signed char c) { return static_cast<unsigned int>(static_cast<unsigned char>(c)); }

  char c = -4;
  std::cout << sch2uint(c);

прямтаки неудобно получилось, я вчера бошка опухла видно совсем, вот как была решена эта задача седня за пару минут
unsigned char array[28*28*100];
file.read((char*)array,28*28*100);
for (int i =0; i<28*28; i++) cout<<(int)array[i]<<endl;

выводит как раз то что надо, значения в диапазоне от 0 до 255, но все равно спасибо за помощь
PM MAIL   Вверх
jonie
Дата 26.3.2009, 01:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 6
Всего: 118



Цитата

эм что за платформа ? непонял.
http://ru.wikipedia.org/wiki/Порядок_байтов
Цитата

На функцию компилятор выдает непонятную ошибку, 
  [Linker error] undefined reference to `ntohl@4' 
подключите библиотеку Ws2_32.lib . Для MSVC можно так:
Код

#pragma comment(lib,"Ws2_32.lib")


см. http://msdn.microsoft.com/en-us/library/ms740069(VS.85).aspx

Добавлено через 59 секунд
если, конечно, вам вообще нужно что-то переворачивть 8))


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
cupper
Дата 26.3.2009, 11:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 525
Регистрация: 29.11.2006

Репутация: нет
Всего: 1



а не в вижаке как добовлять ?) если в Dev-C++ компилю то #pragma comment(lib,"Ws2_32.lib") както особо нече неменяет :(
блин скокож гемороя в это затеи

Это сообщение отредактировал(а) cupper - 26.3.2009, 11:40
PM MAIL   Вверх
mrgloom
Дата 27.4.2012, 09:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



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

Код

int reverseInt (int i) 
{
    unsigned char c1, c2, c3, c4;

    c1 = i & 255;
    c2 = (i >> 8) & 255;
    c3 = (i >> 16) & 255;
    c4 = (i >> 24) & 255;

    return ((int)c1 << 24) + ((int)c2 << 16) + ((int)c3 << 8) + c4;
}
void read_mnist(/*string full_path*/)
{
        ifstream file ("C:\MNIST\t10k-images-idx3-ubyte.gz");
        if (file.is_open())
        {
                int magic_number=0;
                int number_of_images=0;
                int n_rows=0;
                int n_cols=0;
                file.read((char*)&magic_number,sizeof(magic_number));
                magic_number= reverseInt(magic_number);
                file.read((char*)&number_of_images,sizeof(number_of_images));
                number_of_images= reverseInt(number_of_images);
                file.read((char*)&n_rows,sizeof(n_rows));
                n_rows= reverseInt(n_rows);
                file.read((char*)&n_cols,sizeof(n_cols));
                n_cols= reverseInt(n_cols);
                for(int i=0;i<10000/*number_of_images*/;++i)
                {
                        for(int r=0;r<28/*n_rows*/;++r)
                        {
                                for(int c=0;c<28/*n_cols*/;++c)
                                {
                                        unsigned char temp=0;  
                                        file.read((char*)&temp,sizeof(temp));//непонятно постоянно выдает нули
                                }
                        }
                }
        }
}




Цитата

Quote
TEST SET IMAGE FILE (t10k-images-idx3-ubyte):

[offset] [type] [value] [description] 
0000 32 bit integer 0x00000803(2051) magic number 
0004 32 bit integer 10000 number of images 
0008 32 bit integer 28 number of rows 
0012 32 bit integer 28 number of columns 
0016 unsigned byte ?? pixel 
0017 unsigned byte ?? pixel 
........ 
xxxx unsigned byte ?? pixel
Pixels are organized row-wise. Pixel values are 0 to 255. 0 means background (white), 255 means foreground (black).

PM MAIL   Вверх
bsa
Дата 27.4.2012, 15:29 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



На будущее: "MSB first" происходит от "most significant byte first", что в переводе значит - старший байт идет первым. Процессоры Intel/AMD имеют платформу little endian, где старший байт идет в конце. Поэтому числа надо "переворачивать".
Но я бы просто сделал так:
Код
unsigned short beRead16(std::istream &stream) //be - from BigEndian
{
   unsigned short ret = 0;
   ret = static_cast<unsigned short>(stream.get()) << 8;
   ret = ret | static_cast<unsigned char>(stream.get());
   return ret;
}

unsigned beRead32(std::istream &stream) //be - from BigEndian
{
   unsigned ret = beRead16(stream) << 16;
   return ret | beRead16(stream);
}

PM   Вверх
mrgloom
Дата 27.4.2012, 17:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



ну int я и так переворачивал, а char это ведь и есть byte чего его переворачивать?

п.с.  
Код

unsigned beRead32(std::istream &stream) //be - from BigEndian

тут пропущено long?
PM MAIL   Вверх
bsa
Дата 27.4.2012, 22:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



mrgloom, ничего тут не пропущено. Конечно, если ты пишешь программу под процессор, разрядность которого ниже 32-х битов, то да, long необходим.
PM   Вверх
mrgloom
Дата 28.4.2012, 09:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 829
Регистрация: 8.6.2011

Репутация: нет
Всего: нет



а что просто unsigned это тип данных? или я как то функцию не понял.


и еще возможно что под  unsigned byte они имели ввиду что то отличное от unsigned char?  

PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0660 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.