16進文字列(char [])をintに変換しますか?


82

「0x1800785」などの値を含むchar []がありますが、値を指定する関数にはintが必要です。これをintに変換するにはどうすればよいですか?探し回ったのですが、答えが見つかりません。ありがとう。


回答:


209

試しましたstrtol()か?

strtol-文字列を長整数に変換します

例:

数値の文字列表現が0xプレフィックスで始まる場合は、ベースとして0を使用する必要があります。

(16などの明示的なベースを指定することも可能ですが、冗長性を導入することはお勧めしません。)


4
"0x"質問で指定されているように、hexstringが常にによって導入される場合は、の0代わりに使用する必要があり16ます。
Jens Gustedt 2012

16
@KelvinHu cplusplus.comを信用しないでください、それはがらくたです。もしあれば、cppreference.comにアクセスしてください

1
@KelvinHuそのサイトには、技術的に正しくない、または緩い言い回しの情報がたくさんあります。SOの周りにC ++プログラマーがいる場合、この理由から、すべてのプログラマーはそれに依存することを思いとどまらせます。

1
@ H2CO3はい、わかりました。私はC ++を初めて使用するので、これをgoogleで検索すると、cplusplus.comが最前面に配置されます。本当にあなたの情報に感謝します。
Kelvin Hu

3
補足として、非常に大きなヘクスを扱うときに最適なstrtolタイプlongを示します。さらに大きなヘクスのstrtollタイプlong longに使用します。
Steven Lu

20

または、独自の実装が必要な場合は、例として次のクイック関数を作成しました。


1
マイクロコントローラーのようにリソースが限られているプラ​​ットフォームに非常に役立ちます。
Mubin Icyer 2018

19

このようなものが役立つ可能性があります:

mansscanfを読む


1
これにより、未定義の動作が発生%xしますunsigned int。のアドレスを受け取る必要があります。あなたはそれを修正しても文字列によって表される数よりも大きい場合、UINT_MAXそれは未定義の動作は再びです
MM

10

文字列だとしたら、strtolはどうですか?


私はもともとstrtolではなくstrtod(-> double)にリンクしていました。私が編集しているときに誰かがそれを見たと思います。
James McLaughlin

まあ、それは大した間違いではありません...コンパイラはに供給された場合に戻り値を自動キャストしますint。+ 1、ところで。

doubleが32ビット整数で可能なすべての値を格納できるとは思いません(実際、これが正しいかどうかは誰か知っていますか?私は浮動小数点数の表現に100%ではありません)
James McLaughlin

4
@JamesMcLaughlinできます。64ビットIEEEダブルの積分精度は約2 ^ 53です。

詳細、「64ビットIEEEダブルの積分精度は約2 ^ 53です。」と符号ビット。だから、扱うことができるint54_tuint53_t
chux -復活モニカ

5

strtolトップアンサーが示唆するようにlibcを利用できる場合に使用します。ただし、カスタムのものが好きな場合、またはlibcなどのないマイクロコントローラーを使用している場合は、複雑な分岐のないわずかに最適化されたバージョンが必要になる場合があります。

ビットシフトの魔法は次のように要約されます。最後の4ビットを使用しますが、それが数字以外の場合は、9も追加します。


機会があれば、「v =」行のしくみについてもう少し詳しく説明していただけますか?:次のように私は自分の目的のために、あなたの機能を実装するために管理unsigned long long int hextou64(char *str) { unsigned long long int n = 0; char c, v; for (unsigned char i = 0; i < 16; i++) { c = *(str + i); v = (c & 0xF) + (c >> 6) | ((c >> 3) & 0x8); n = (n << 4) | (unsigned long long int)v; } return n; }
iamoumuamua

これをまだまとめられるかどうか見てみましょう^^かなりトリッキーだと思います。前提:「0」から「9」はすべて「0011 ????」で始まります。バイナリで。「A」-「F」はすべて「0100 ????」で始まります バイナリで。この情報を使用して、分岐を回避できます。(c&0xF)→最後の4ビットのみに値が含まれます。これはすでに「0」から「9」の正しい値です。'A'-'F'の場合、正しい値を取得するには、小数点以下9を追加する必要があります。(たとえば、16進数Cは0011で終わります。これは3です。ただし、12が必要です。したがって、9を追加する必要があります。 (c >> 6) | ((c >> 3) & 0x8)→文字の場合は9、小数の場合は0と評価されます。はい、かなりハッキーです:)
LimeRed

3

以下のコードブロックを試してみてください。

出力は次のとおりです。


3

そのため、しばらく検索して、strtolが非常に遅いことがわかった後、独自の関数をコーディングしました。文字の大文字に対してのみ機能しますが、小文字の機能を追加しても問題はありません。

使用法:

1は、変換する16進数がオフセット1から始まるため、8は16進数の長さであるためです。

スピードテスト(1.000.000コール):


2

1つの迅速で汚い解決策:

入力が正しく、検証が含まれていないことを確認する必要があります(Cであると言えます)。非常にコンパクトで、「A」から「F」と「a」から「f」の両方で機能するのは良いことです。

このアプローチは、ASCIIテーブル内のアルファベット文字の位置に依存しています。たとえば、ウィキペディア(https://en.wikipedia.org/wiki/ASCII#/media/File:USASCII_code_chart.png)を見てみましょう。簡単に言うと、数字は文字の下にあるため、数字(0〜9)は、ゼロのコードを引くことで簡単に変換できます。アルファベット文字(AからF)は、最後の3ビット以外のゼロ(大文字または小文字のいずれかで効果的に機能するようにする)、1を引く(ビットマスキングの後、アルファベットは位置1から始まるため)、および10を加算することによって読み取られます( AからFは、16進コードで10番目から15番目の値を表すためです)。最後に、エンコードされた数値の下位ニブルと上位ニブルを形成する2桁を組み合わせる必要があります。

ここでは、同じアプローチを使用します(わずかなバリエーションがあります)。


1
答えを投稿した後、私は@LimeRedの投稿を見逃したことがわかりました。これはとてもかわいいです
Simon

1

これは、char配列を含む16進数を、追加のライブラリを必要としない整数に直接変換する関数です。


0

を使用せずに16進数と10進数の変換を行うためのライブラリを作成しましたstdio.h。使い方はとても簡単です:

最初の変換の前に、変換に使用される配列を次のように初期化します。

ここにgithubのリンクがありますhttps//github.com/kevmuret/libhex/


0

私は同じようなことをしました、それはあなたが実際に私のために働いているのを助けるかもしれないと思います

ここでは、8文字の文字列のみを取得しました。'a'から 'f'に同様のロジックを追加して、同等の16進値を指定できるようにしたい場合は、それを実行していません。そのため、必要ありませんでした。


-5

私はこれが本当に古いことを知っていますが、解決策はあまりにも複雑に見えたと思います。VBでこれを試してください:

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.