Подскажите, почему не выводится один байт?

Тема в разделе "LANGS.C", создана пользователем ajak, 5 окт 2008.

  1. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    А выводиться 2

    Код (Text):
    1. #include <stdio.h>
    2. void main()
    3. {
    4.  FILE *in;
    5.  char buf[20];
    6.  in=fopen("c:\\1.bin","rb");
    7.  fread(buf,1,1,in);
    8.  printf("%x",buf[0]);
    9. }
    Вывод -ffff
    Почему два байта, ведья читаю один и char это один байт.
     
  2. rmn

    rmn Well-Known Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2004
    Сообщения:
    2.348
    Код (Text):
    1. printf("%02x",buf[0]);
     
  3. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    buf[0] имеет тип char, при вызове printf преобразуется в int знаковым расширением. Например, 0xFF -> 0xFFFF [судя по выводу, система 16-битная - под 32-битной было бы 0xFFFFFFFF]. А потом printf, которая не в курсе, что исходный параметр был char, видит спецификацию %x и думает, что ей передали int, который нужно вывести целиком в hex-виде. К примеру, если бы первый байт был 0xE8, то вывелось бы ffe8, а если 0x4D, то просто 4d.
    Пиши "unsigned char buf[20]" либо явно преобразуй к unsigned char типа "printf(...,(unsigned char)buf[0]);".
     
  4. s0larian

    s0larian New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2004
    Сообщения:
    489
    Адрес:
    Крыжёпполь
    diamond, ты описал следствие. Причина в том что обычно "char" есть signed.

    Fix:
    Код (Text):
    1. unsigned char buff[32];
     
  5. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Так это только внешний вид, правильно? Внутри этой переменной храниться же верное значение? Байт?
     
  6. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Нет, у меня XP pro обычный и проц 64-битный. Почему так тогда?


    Не понял, а какая здесь разница? Почему в одном случае с ff, в другом без.
     
  7. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Ну тогда 0xffffffffffffffff ;)
    Обнули буфер перед чтением.
     
  8. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Угу.
    Имелась в виду не ось, под которой всё это происходит, а ось, под которую исходник компилируется. Под DOSовскими компиляторами в DOS-подсистеме всё происходящее 16-битное. (Если компилятор не DOSовский, а, к примеру, под Win3.x, сути дела это не меняет.) Кстати, при работе под обычной (не 64-битной) XP абсолютно безразлично, поддерживает проц 64-битный режим или нет.
    Вот есть переменная типа char. Который знаковый. То есть записанное там значение по определённым правилам соответствует какому-то числу из отрезка [-128,127]. При преобразовании такого значения в тип int компилятор делает так, чтобы преобразованное значение было тем же самым числом из отрезка [-128,127]. Если старший бит байта установлен, то такой байт соответствует отрицательному числу, и при записи этого же числа в двух байтах согласно тем же правилам старший байт будет равен 0xFF. В противном случае получится 0. А ведущие нули printf("%x",...) не печатает.
     
  9. ajak

    ajak New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2007
    Сообщения:
    463
    Большое спасибо. Всё понял :) Ура товарищи