The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Просмотр байтов файла, !*! victorddt, 07-Фев-05, 15:22  [смотреть все]
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <unistd.h>

#define BSIZE 1

int main()
{
FILE *in, *out;
char *buffer[BSIZE], mask;
int act_read;

in=fopen("1.JPG","rb");
out=fopen("1_1.JPG","wb");

do
{
  act_read=fread(*buffer,1,BSIZE,in);

  printf("%x\n",(int)*buffer[0]);

  fwrite(*buffer,1,act_read,out);
}while (act_read == BSIZE);


fclose(in);
fclose(out);
}

Сдесь читается файл 1.jpg и выводятся значения его байтов (на запись в другой файл внимания не обращать).
Допустим байты имходной картинки такие:
FF D8 FF E0 00 10 4A 46

Он мне пишет:
ffffffff
ffffffd8
ffffffff
ffffffe0
0
10
4a
46

Почему пишется:
ffffffff
ffffffd8
ffffffff
ffffffe0

а не:
ff
d8
ff
e0

?

  • Просмотр байтов файла, !*! Maxim Kuznetsov, 17:01 , 07-Фев-05 (1)
    копать в сторону преобразования знакового char в int
    (один БАЙТ это вообщето UNSIGNED char)
    вот у тебя все байты с еденичным старшим битом и перепахались в отрицательные целые ;-)


  • Просмотр байтов файла, !*! Maxim Kuznetsov, 17:53 , 07-Фев-05 (2)
    если приведенный фпйгмент получен методом cut&paste,
    то оригинал пашет по памяти ;-)
    ---
    вообще - хороший пример !
    (далее тест для всех)
    попробуйте подсчитать кол-во ошибок
    и сравните результат с выводом lint (splint)..

    • Просмотр байтов файла, !*! Alexander S. Salieff, 20:28 , 07-Фев-05 (3)
      >если приведенный фпйгмент получен методом cut&paste,
      >то оригинал пашет по памяти ;-)
      >---
      >вообще - хороший пример !
      >(далее тест для всех)
      >попробуйте подсчитать кол-во ошибок
      >и сравните результат с выводом lint (splint)..


      Стопудово пашет. Непонятно, почему в сегфолт не валится, наверное потому что BSIZE слишком маленький...

      victorddt, смотри:
      char *buffer[BSIZE], mask; Это ты объявил массив из одного указателя на char(который на данный момент указывает хз куда).
      act_read=fread(*buffer,1,BSIZE,in); *buffer = *(&buffer[0]) = buffer[0], это ты читаешь данные в ту память, куда указывает твой указатель buffer[0] (а он, как мы помним, указывает хз куда).
      Т.е. в лучшем случае ты бесконтрольно перезаписываешь данные своей программы, в худшем ловишь ошибку сегментации.
      Если тебе так вперлось столь уродское объявление, то сделай так:
      char *buffer[BSIZE], mask;
      ...
      for (int i=0; i<BSIZE; i++) buffer[i]=malloc(BSIZE);
      ... //Работаем с массивом
         printf("%02X\n",(unsigned int)((unsigned char)(*((unsigned char *)buffer[0])))); // Тут изза дураццких указателей приходится воротить огород с приведением типов
      for (int i=0; i<BSIZE; i++) free(buffer[i]);

      А по людски люди пишут
      unsigned char buffer[BSIZE];
      ...
      act_read=fread(buffer,BSIZE,1,in); // Гораздо быстрее читать один блок размером BSIZE, чем BSIZE блоков размером 1 байт, хотя здесь это не важно, ибо BSIZE=1
      printf("%02X\n",(unsigned int)buffer[0]); // При такой записи все должно быть ровно с выводом, потому что нет хитромудрой пляски с указателями, данные строго типизированы
      ...
        }while (act_read == 1);

    • Просмотр байтов файла, !*! victorddt, 08:48 , 08-Фев-05 (5)
      >если приведенный фпйгмент получен методом cut&paste,
      >то оригинал пашет по памяти ;-)
      >---
      >вообще - хороший пример !
      >(далее тест для всех)
      >попробуйте подсчитать кол-во ошибок
      >и сравните результат с выводом lint (splint)..


      Так, так, так. Спокойно! Нечего глумиться над неопытными :) Я это за 2 дня унал и написал!

  • Просмотр байтов файла, !*! Alexander S. Salieff, 20:44 , 07-Фев-05 (4)
    Еще в догонку - цикл файловых ио-операций организован неверно, если твой fread обламывается с операцией, то ты все равно пишешь буффер в файл, хоть там и лабуда содержится. Нормальный цикл должен выглядеть приблизительно так (хоть он и некрасивый, но всяко эффективнее твоего)

    unsigned char buffer[BSIZE];
    size_t act_read;
    long pos=0, now_pos;
    int really_read;

    while(true)
    {
    act_read=fread(buffer, BSIZE, 1, in);
    now_pos=ftell();
    really_read = now_pos - pos;
    pos=now_pos;
    if (really_read>0)
      {
      if (fwrite(buffer, really_read, 1, out)!=1)
        perror(.....
      И чего-то там еще
      }
    else
      {
      if (!feof(in))
        perror(..... Типа у нас проблемы и все такое
      break;
      }
    }

    Вся лабуда с ftell'ами и рассчетом позиций для повышения скорости чтения при больших BSIZE

    • Просмотр байтов файла, !*! victorddt, 09:47 , 08-Фев-05 (6)
      Я сделал вот так:

      #include <stdio.h>
      #include <stdlib.h>
      #include <sys/stat.h>
      #include <unistd.h>

      #define BSIZE 1

      int main()
      {
          FILE *in, *out;
          unsigned char buffer[BSIZE];
          size_t act_read;
          long pos=0, now_pos;
          int really_read;

          in=fopen("1.JPG","rb");
          out=fopen("1_1.JPG","wb");

          while(1)
          {
              act_read=fread(buffer, BSIZE, 1, in);

              if(act_read > 0)
              {
                  fwrite(buffer, act_read, 1, out);
              }
              else
              {
                  break;
              }
          }
      }

      С real_pos'ом писался только 1 байт. Так работает. Спасибо за пример. Стало понятно и просто. :)




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру