5

最初に、英語の間違いをお詫びしますが、15 歳でフランス語は役に立ちません...

ファイル形式仕様 ( http://www.libpng.org/pub/png/spec/1.2/PNG-Contents.html )を使用して PNG デコーダーをプログラムしようとしていますが、奇妙な問題に遭遇しました。

仕様によると、PNG ファイルの最初の 8 バイトには常に次の (10 進数) 値が含まれます: 137 80 78 71 13 10 26 10.

この単純なプログラムをテストすると:

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

    string line;
    getline(file, line);

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

出力は、ASCII テーブルで 137 を表す「ë」です。よし、最初のバイトと一致する。

ただし、実行するint ascii_value = line[0];と、出力値は -119 になり、これは正しい ascii 値ではありません。

「e」のような別の文字で同じことを試みると、正しい ascii 値が出力されます。

誰かが私が間違っていることと解決策を説明できますか? 個人的には拡張ASCIIテーブルの問題だと思いますが、よくわかりません。

みんなありがとう!signed char を unsigned char にキャストします

4

6 に答える 6

10

システムのchar型は符号付きです。そのため、値が負になる可能性があります。

明示的で、記号を削除する必要があります。

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

あなたのマシンが使用しているように見える2の補数で -119 = 137 であることに注意してください。したがって、ビット自体は本当に正しいので、正しく解釈することがすべてです。

于 2013-01-28T15:52:46.977 に答える
5

charC++では、符号付きまたは符号なしの両方にすることができます1)、それは実装次第です。あなたのコンパイラの場合(実際にはほとんどの場合)、署名されているように見えます:

128 を超える文字値は、負の数として表されます。-119 はたまたま符号なし文字値 137 に対応しています。つまり、次のことが成り立ちます。

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

ただし、これは実装固有であるため、一般にこれらの値に依存できないことに注意してください。


1) And は、 and の両方とは異なるタイプです。signed charunsigned char

于 2013-01-28T15:52:13.987 に答える
4

ASCII は 0 .. 127 のみをカバーします。ASCII テーブルには 137 はありません。

「拡張 ASCII テーブル」のようなものもありません。多数の (相互に互換性のない) ASCII 拡張機能があります。技術的には、Unicode でさえ「拡張 ASCII」です。

charコンパイラは-128から127までの値をカバーする符号付きの型であるため、-119を取得しています(-119は137から256です)。に明示的にキャストすることで、期待する値を取得できますunsigned char

int value = static_cast<unsigned char>(line[0]);
于 2013-01-28T15:52:54.313 に答える
0

137 = -119 = 0x89。をキャスト(unsigned) (unsigned char)(line[0])すると、137 の整数値が表示されます。

char( の基本型std::string) は [通常] 符号付きの値で、範囲は -128 ~ 127 です。127 より大きい値は負の数になります。

于 2013-01-28T15:53:37.513 に答える
0

charC++は、 が符号付きか符号なしかを指定しません。これは、「拡張」ASCII 文字 (0..127 の範囲外で、最上位ビットが設定されているもの) が負の値として解釈される可能性があることを意味します。それがあなたのコンパイラが行うことのようです。

unsigned char期待している符号なしの値を取得するには、明示的に型に変換する必要があります。

int ascii_value = static_cast<unsigned char>(line[0]); // Should be 137
于 2013-01-28T15:57:13.713 に答える
0

符号拡張を許可すると、このようになります。拡張 ASCII テーブルの文字には、上位ビット (符号ビット) が設定されています。

-119は0x89。137もあり0x89ます。

試す

int ascii_value = line[0] & 0x00FF;

また

int ascii_value = (unsigned char)line[0];
于 2013-01-28T15:52:29.683 に答える