|
Компьютерный форум OSzone.net » Программирование, базы данных и автоматизация действий » Программирование и базы данных » C/C++ - Бинарные файлы |
|
|
C/C++ - Бинарные файлы
|
Новый участник Сообщения: 21 |
Профиль | Отправить PM | Цитировать
Решено
|
|
Отправлено: 12:52, 20-04-2009 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать |
Отправлено: 15:12, 20-04-2009 | #2 |
Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети. Если же вы забыли свой пароль на форуме, то воспользуйтесь данной ссылкой для восстановления пароля. |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать |
Отправлено: 13:58, 21-04-2009 | #3 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать .::.DIMA.::., fread нет необходимости знать структуру
К примеру по ссылке можно добавить следующий код, что б увидеть, а что хоть считало /* the whole file is now loaded in the memory buffer. */ //... for (int i=0;i<result;i++) printf("%c",buffer[i]); //... // terminate В случае с fprintf / fscanf нужно задавать параметр считывания, впрочем можно ведь задать как unsigned char, а уже в цикле как по приведённом выше коде, распознать что есть что. pva, в случаи символа, как наименьшего элемента файла, один символ = один байт. А вот в случаи с UNICODE текста - один печатный символ уже не один байт. |
Последний раз редактировалось Admiral, 21-04-2009 в 14:47. Отправлено: 14:08, 21-04-2009 | #4 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата Admiral:
|
||
Отправлено: 07:38, 22-04-2009 | #5 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать pva насчёт юникода, тут есть пользовательский момент: если воспользоваться примером выше для чтения файла сохранённого в Юникоде, то после каждого символа будут пробелы (текст на английском, для других языков не проверял). Это удивит пользователя, который не будет наблюдать последних при просмотреть через блокнот. В этом случаи, как я понимаю, или самостоятельно убирать пробелы, или же юзать юникод версии функций чтения/записи и соответственные пользовался переменными типа wchar_t.
Хорошо что привели структуру, хотелось бы её обсудить. Если её натравить на любой текстовый файл, то вывод будет в виде абракадабры Цитата Фрагмент данных прочитанных с файла boot.ini приведённым примером:
Цитата Фрагмент данных с сохраненного программой ниже файла, при просмотре Word'ом:
И дело тут не в режиме открытия t/b, которые отличаются только тем, что в первом случаи перевод каретки (Ентер) и новая строчка это один символ, а во втором два отдельных, а в том что так оно устроено. Собственно сама программа чтения/записи, с использованиям приведённой структуры. Поля, да и сама структура, используются явно не по назначению, приведено только для примера. #include <stdio.h> #include <stdlib.h> struct row_t { char id[8]; char name[100]; char description[255]; char _reserved_for_DOS_CR[2]; }; int main(int argc, char* argv[]) { row_t row1[10]; int i; for (i=0;i<10;i++) { sprintf(row1[i].id,"id%d",i); sprintf(row1[i].name,"name%d",i); sprintf(row1[i].description,"description%d",i); sprintf(row1[i]._reserved_for_DOS_CR,"R%d",i); } if (argc>1) { FILE * pFile = fopen ( argv[1] , "wb+" ); if (pFile==NULL) { printf ("File error"); return -1; } fwrite(row1, sizeof(row_t), 10, pFile); rewind(pFile); for (i=0;i<10;i++) { sprintf(row1[i].id,"%d",i); sprintf(row1[i].name,"%d",i); sprintf(row1[i].description,"%d",i); sprintf(row1[i]._reserved_for_DOS_CR,"%d",i); } fread(row1, sizeof(row_t), 10, pFile); for (i=0;i<10;i++) printf("%s %s %s %s\n", row1[i].id, row1[i].name, row1[i].description, row1[i]._reserved_for_DOS_CR); fclose (pFile); } return 0; } Цитата Вывод программы:
При отладки в некоторых средах может появляется сообщение о разрушении стека возле переменной row1. Цитата:
Причём то что далее по тексту идёт затирание чрез i (для того что б убедится что данные берутся именно из файла) всех элементов структуры и элементов массива (от 0 до 10 не включая 10) row1 среда не находит проблемным. Структуры удобны в обработке, но в текстовом виде данные в файлы не сохранишь. Или всё же можно? |
||||
Отправлено: 18:47, 22-04-2009 | #6 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата Admiral:
Цитата Admiral:
Цитата Admiral:
Цитата Admiral:
Пример: запускаем FAR, создаём в нём текст, который содержит ровно 20 строк ровно по 8 + 100 + 255 = 363 символа (пробела). Включаем режим замены (нажимаем INSERT) и заполняем полученные строки (так чтобы длина строки оставалась 363, а "пустые" символы заполнялись пробелами) Начиная с каждого 0 символа строки пишем ID, с каждого 8 name, со 108 - description. На вид получится красивая выровненная табличка. Сохраняем файл и подаём в качестве аргумента к программе. Должно отработать красиво. Конечно же не оптимально хранить данные в таких файлах, где много пробелов, тем не менее, бывают случаи когда это самое элегантное решение, не требующее сложной обработки данных. Например рассмотрим телефонную станцию, после каждого звонка выдаёт следующие строчки: 1. дата (8 симв, ддммгггг) 2. время (6 символов ччммсс) 3. исходящий номер (11 симв) 4. входящий номер (11 симв) 5. время разговора (4 симв) 6. стоимость разговора (10 симв) вот в таком виде: Теперь по поводу ошибок в программе: // думаю причина в использовании аргумента %s с не Null-terminated string // правильный вариант: void print_row(row_t* row) { printf("%8s|%100s|%255s|\n", row->id, row->name, row->description); // static const char* space = "|"; // fwrite(row->id, sizeof(row->id), 1, stdout); // fwrite(space, 1, 1, stdout); // fwrite(row->name, sizeof(row->name), 1, stdout); // fwrite(space, 1, 1, stdout); // fwrite(row->description, sizeof(row->description), 1, stdout); // fwrite(space, 1, 1, stdout); } |
||||
Отправлено: 21:18, 22-04-2009 | #7 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать pva, это про то, как с точки зрения пользователя будет работать программа, читающие так текстовые файлы.
Опять использовал пользовательскую терминологию, на экране он видит пробелы. Спасибо за ликбез, буду знать - "байт 0". Говоря "сырые" я использую терминологию применяемую Харви и Полом Дейтелем, может быть дело в переводе. Тогда мне не понятно, почему находясь в памяти компьютера эти данные имеют читабельный вид, а сохраняясь в файл преображаются в не читаемый вид? А почему именно 20? У нас ведь массив на Чёткость не меньше/не больше, в данном случаи в файле 20 строк, не совсем согласуется с тем, что данные в файле могут свободно обновляться, в том числе сторонней программой, например через блокнот пользователём. К сожалению отображение не получилось #include <stdio.h> struct row_t { char id[8]; char name[100]; char description[255]; char _reserved_for_DOS_CR[2]; }; int main(int argc, char* argv[]) { if (argc>1) { FILE * pFile = fopen ( argv[1] , "rb" ); if (pFile==NULL) { printf ("File error"); return -1; } row_t row1[10]; fread(row1, sizeof(row_t), 10, pFile); for (int i=0;i<10;i++) printf("%s %s %s", row1[i].id, row1[i].name, row1[i].description); fclose (pFile); } return 0; } |
Последний раз редактировалось Admiral, 12-12-2009 в 04:21. Причина: Содержимое откреплённых вложений перенёс в пост Отправлено: 01:48, 23-04-2009 | #8 |
Ветеран Сообщения: 1180
|
Профиль | Отправить PM | Цитировать Цитата Admiral:
union { double d; char c[8]; } value1; value1.d = 0.1; // используем одну и ту же память: printf("%8s", value1.c); // получим галиматью printf("%8lf", value1.d); // получим красоту printf("%8ld", value1.d); // в "с" это можно сделать :( получим галиматью // получим 16-ричное представление памяти, в которой лежит double(0.1) cout << hex << setfill('0') ; for(unsigned i=0; i<8; ++i) cout << setw(2) << static_cast<unsigned>(reinterpret_cast<unsigned char>(c[i])) << " "; Цитата Admiral:
Цитата Admiral:
Цитата Admiral:
|
||||
Последний раз редактировалось pva, 25-02-2012 в 11:59. Отправлено: 08:55, 23-04-2009 | #9 |
Ветеран Сообщения: 3320
|
Профиль | Отправить PM | Цитировать pva, возможно покажусь назойливым, но всё же, возможно ли структуру в читабельном виде сохранить в файл, что б при чтении обратно программа понимала что это структура? В примерах про структуры показывается что нет - только бинарное представление.
В каких случаях стоит использовать union(объединение)? Это ведь таже структура, только более щадящая память за счёт размещения всех полей по одному и тому же адресу. Вместо пробелов всё же хочется задействовать табуляцию. В качестве примера я взял предыдущий - про телефонную станцию. Вот её структура struct PhoneStatistic { char date[8+1]; //1. дата (8 симв, ддммгггг) char time[6+1]; //2. время (6 символов ччммсс) char dialing[11+1]; //3. исходящий номер (11 симв) char incoming[11+1]; //4. входящий номер (11 симв) char duration[4+1]; //5. время разговора (4 симв) char price[10+1]; //6. стоимость разговора (10 симв) char *notes; //7. новое поле переменно не определённой/не известной длины для эксперимента }; Визуально всё хорошо получается (используя printf), да вот возникает сложность сбора данных в поля структуры. Используя printf можно в цикле выводить символы, при этом на экране складывается слово. По идеи, тоже самое можно сделать для полей структуры через sprintf. Да вот не задачка, не проходит. stdout это стандартный поток вывод, а stdin - ввода. Возможно, ли каким-то образом используя их комбинацию заполнять поля структуры данными выводимыми printf'ом? То есть что б они брались с экрана? Возможно ли во время выполнения программы узнать количество полей/элементов структуры? Так как в программе приходится за каждым элементом закреплять свой цикл. Отличие, от данных которые привёл pva выше - в добавленной табуляции между полями + новое поле. |
Последний раз редактировалось Admiral, 12-12-2009 в 04:32. Причина: Содержимое откреплённых вложений перенёс в пост Отправлено: 20:29, 25-04-2009 | #10 |
|
Участник сейчас на форуме | Участник вне форума | Автор темы | Сообщение прикреплено |
| |||||
Название темы | Автор | Информация о форуме | Ответов | Последнее сообщение | |
Не открываются текстовые файлы и изображения и к ним создались файлы с расшир. drweb | leda | Лечение систем от вредоносных программ | 1 | 03-10-2009 01:22 | |
[решено] Не удаляются неизвестные мне файлы fidbox.dat и fidbox.idx. Что это за файлы? | segafos | Лечение систем от вредоносных программ | 31 | 04-06-2009 17:17 | |
CMD/BAT - файлы вида mmdd*.* - для каждой даты нужно создать каталог, скопировать, файлы | milito | Скриптовые языки администрирования Windows | 2 | 24-05-2009 23:32 | |
Доступ - html-файлы грузятся как файлы для скачивания | Dr. MefistO | Microsoft Windows 2000/XP | 1 | 08-03-2009 10:06 | |
Файлы | Surround | Вебмастеру | 4 | 28-03-2003 08:35 |
|