png — неверное значение ASCII (& quot; с & quot;)

Во-первых, я прошу прощения за любые ошибки на английском, которые я сделаю, но быть 15 и французский не помогает …

Я пытаюсь запрограммировать декодер PNG с помощью спецификации формата файла (http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html) но я столкнулся со странной проблемой.

В спецификации говорится, что первые восемь байтов файла PNG всегда содержат следующие (десятичные) значения: 137 80 78 71 13 10 26 10.

Когда я тестирую эту простую программу:

int main()
{
ifstream file("test.png");

string line;
getline(file, line);

cout << line[0] << endl;
}

Выход «ë», который представляет 137 в таблице ascii. Хорошо, это соответствует первому байту.

Тем не менее, когда я делаю int ascii_value = line[0];выходное значение равно -119, что не является правильным значением ASCII.

Когда я пытаюсь сделать то же самое с другим символом, таким как «e», он выводит правильное значение ascii.

Может кто-нибудь объяснить, что я делаю не так и каково решение? Я лично думаю, что это проблема с расширенной таблицей ASCII, но я не уверен.

Спасибо всем ! Я брошу свой подписанный символ на неподписанный !

5

Решение

Ваша система char Тип подписан, поэтому его значения могут быть отрицательными.

Вы должны быть явными и опустить знак:

const unsigned char value = (unsigned char) line[0];

Обратите внимание, что -119 = 137 в дополнение двух который использует ваша машина. Так что сами биты действительно верны, все дело в их правильной интерпретации.

10

Другие решения

char в C ++ может быть как подписанным, так и неподписанным1), это до реализации, которая это. В случае вашего компилятора (как в большинстве случаев, на самом деле) он, кажется, подписан:

Любое символьное значение> 128 представляется как отрицательное число. -119 соответствует неподписанный значение символа 137. Другими словами, имеет место следующее:

unsigned char c = 137;
assert(static_cast<signed char>(c) == -119);

Но обратите внимание, что это зависит от реализации, поэтому вы не можете в целом полагаться на эти значения.


1) И является отличный тип от обоих signed char а также unsigned char,

5

ASCII охватывает только 0 .. 127. В таблице ASCII нет 137.

Также нет такой вещи как «расширенная таблица ASCII». Существуют десятки (взаимно несовместимых) расширений ASCII. Черт, технически даже Unicode — это «расширенный ASCII».

Вы получаете -119, потому что в вашем компиляторе char тип со знаком, охватывающий значения от -128 до 127. (-119 — 137 — 256). Вы можете получить ожидаемое значение, явно приведя к unsigned char:

int value = static_cast<unsigned char>(line[0]);
4

Вот что происходит, когда вы разрешаете расширение знака. Символы в расширенной таблице ASCII имеют свой старший бит (знаковый бит).

-119 это 0x89, 137 также 0x89,

Пытаться

int ascii_value = line[0] & 0x00FF;

или же

int ascii_value = (unsigned char)line[0];
0

137 = -119 = 0х89. Если вы бросили (unsigned) (unsigned char)(line[0]), вы получите его, чтобы напечатать целое значение 137.

Тип char (который является базовым типом для std::string) [обычно] значение со знаком, в диапазоне от -128-127. Все, что выше 127, будет отрицательным числом.

0

C ++ не указывает, является ли char является подписанным или неподписанным типом. Это означает, что «расширенные» символы ASCII (те, которые находятся вне диапазона 0..127 с установленным верхним битом) могут интерпретироваться как отрицательные значения; и похоже, что это то, что делает ваш компилятор.

Чтобы получить ожидаемое значение без знака, вам нужно явно преобразовать его в unsigned char тип:

int ascii_value = static_cast<unsigned char>(line[0]); // Should be 137
0
По вопросам рекламы [email protected]