文字の数字をCの対応する整数に変換する


103

Cで文字を整数に変換する方法はありますか?

たとえば、'5'5から5ですか?

回答:


147

他の返信と同様に、これは問題ありません。

char c = '5';
int x = c - '0';

また、エラーチェックの場合は、最初にisdigit(c)がtrueであることを確認することをお勧めします。たとえば、文字に対して完全に移植可能に同じことを行うことはできないことに注意してください。次に例を示します。

char c = 'b';
int x = c - 'a'; // x is now not necessarily 1

標準では、数字の「0」から「9」までのchar値が連続していることを保証していますが、アルファベット文字などの他の文字については保証していません。


3
@Paul Tomblin:答えで述べたように、標準では「0」から「9」までの連続が保証されていますが、「a」から「z」などの他の文字についてはこのような保証はないため、文字ではなく数字についてはそうです。
Chris Young、

char c = 'b'; int x = c-'a'; 次に、xはASCIIでのみ1になりますか?
2013年

@Pan ASCIIを含め、「b」が「a」より1つ多い任意のエンコーディング。== 8 -これはまだしかし、それは(「I」「J」)を行い、EBCDICにも当てはまる
クリス・ヤング

@ChrisYoungなんで?EBCDICの原因、「j」は「i」より1だけ大きくない?
2013

2
atoiを使用していない場合、何が欠けていますか?
ダニエル

41

このように「0」を減算します。

int i = c - '0';

C標準は、範囲内の各桁が保証'0'..'9'(セクションでその前の数字よりも1つの大きい5.2.1/3C99ドラフト)。C ++の場合も同様です。


1
この答えは、charが/ already /実質的に整数であり、実装で定義された符号のアルビエット(つまり、符号付きまたは符号なしの可能性がある)であり、CHAR_BITSの長さであると述べた方がよいでしょう。
アラファンギオン2009年

私はそれが本当に彼を助けることを知っていましたかわかりませんでした。しかし、クリスはa..zが必ずしも隣接していないという点で良い点を作りました。代わりにそれを述べるべきだった。現在、彼はレースで優勝しています:)
ヨハネスシャウブ-litb

1
あなたの答えは適格であるので、あなたのほうが良いです-クリスは彼の物事を非常によく作ったかもしれません。:)
Arafangion 2009年

感謝してくれてありがとう。Cの状態がわからないことを認めたので、調べてみたところ、すでに参照していたので、参照を回答に貼り付けました:)
Johannes Schaub-litb 2009年

そして、それが、あなたが私よりも2、3ポイント多い理由です。:)
Arafangion 2009年

29

たまたま偶然に、文字列を整数に変換したい場合も、それを実行できます。

char *num = "1024";
int val = atoi(num); // atoi = ASCII TO Int

valどうやら問題atoi()はなく、以前に私が言ったことは私にのみ適用されます(OS X(多分(ここにLispジョークを挿入)))。strtol()代わりに、より汎用的な関数であるを使用して変換を行う次の例に大まかにマップするマクロであると聞きました。

char *num = "1024";
int val = (int)strtol(num, (char **)NULL, 10); // strtol = STRing TO Long

strtol() このように動作します:

long strtol(const char *str, char **endptr, int base);

これはに変換*strlongれ、基本base数であるかのように扱われます。**endptrがnullでない場合は、最初にstrtol()見つかった数字以外の文字を保持します(ただし、誰がそれを気にするか)。


atoiにはスレッドの問題はなく(静的データはありません)、非推奨ではありません。実際、機能的には次と同等です。#define atoi(x)(int)(strtol((x)、NULL、10)
Evan Teran

5
atoiの問題は、「ここに数値が見つかりません」の値として0を使用することです。そのため、atoi( "0")とatoi( "one")はどちらも0を返します。それを再利用するには、strtol()またはsscanf()を探します。
David Thornley

もちろん、strtolのもう1つの利点は、数値の後に続く同じ文字列から他のものを読み取る必要がある場合があることです。
dfeuer

@EvanTeran残念ながらVisual Studioを実行すると、減価償却の警告が表示されます(無効にしないとコンパイルできません)。VSは現在推奨していitoa_s()ます。
Simon

7

次のようにchar '0'またはint 48を減算します。

char c = '5';
int i = c - '0';

説明:内部的にはASCII値で動作します。ASCIIテーブルから、文字5の 10進数値は53で0は48です。そう 53-48 = 5

または

char c = '5';
int i = c - 48; // Because decimal value of char '0' is 48

つまり、任意の数字から48を差し引くと、整数が自動的に変換されます。


6
char numeralChar = '4';
int numeral = (int) (numeralChar - '0');

numeralChar - '0'はすでにタイプintなので、キャストは必要ありません。そうでなかったとしても、キャストは必要ありません。
Alok Singhal、

ええ、ええ、それは強要でしょうね?たぶんJavaが私の認識に色を付けたのかもしれません。または、多分私は完全に誤っており、Javaでさえ強制されます。:)
ケビン・コナー2010年

5

文字の数字を対応する整数に変換します。以下のようにしてください:

char c = '8';                    
int i = c - '0';

上記の計算の背後にあるロジックは、ASCII値で遊ぶことです。文字8のASCII値は56、文字0のASCII値は48です。整数8のASCII値は8です。

2つの文字を減算すると、文字のASCII間で減算が行われます。

int i = 56 - 48;   
i = 8;

なぜ私だけがこれに賛成するのですか?説明はとてもシンプルで有益です:+1:
Brandon Benefield '

0

ASCIIの0〜9の単一文字の場合は、ASCII値からASCIIゼロ文字の値を引くとうまくいきます。

より大きな数を変換したい場合は、次のようにします:

char *string = "24";

int value;

int assigned = sscanf(string, "%d", &value);

**ステータスを確認することを忘れないでください(上記のケースで機能した場合は1である必要があります)。

ポール。


0
char chVal = '5';
char chIndex;

if ((chVal >= '0') && (chVal <= '9')) {

    chIndex = chVal - '0';
}
else 
if ((chVal >= 'a') && (chVal <= 'z')) {

    chIndex = chVal - 'a';
}
else 
if ((chVal >= 'A') && (chVal <= 'Z')) {

    chIndex = chVal - 'A';
}
else {
    chIndex = -1; // Error value !!!
}

0

このようなことをする必要があるときは、必要な値で配列をプリベイクします。

const static int lookup[256] = { -1, ..., 0,1,2,3,4,5,6,7,8,9, .... };

その後、変換は簡単です

int digit_to_int( unsigned char c ) { return lookup[ static_cast<int>(c) ]; }

これは基本的に、ctypeライブラリの多くの実装で採用されているアプローチです。これを16進数でも機能するように簡単に調整できます。


これは、1つの10進数(または8進数)の数字を変換するのには非常に非効率的です。ルックアップテーブルの関連部分がたまたまL1キャッシュにない場合、1つの値を取得するためだけにそれをプルするために一連のサイクルを吹き飛ばします。率直に言って、たくさんの数字を変換する場合、これが良い考えであるかどうか疑問に思う傾向がありますが、それを測定する必要があります。もちろん、それはヘクスにとってはるかに競争力があります。
dfeuer

0

これをチェックして、

char s='A';

int i = (s<='9')?(s-'0'):(s<='F')?((s-'A')+10):((s-'a')+10);

0、1、2、....、E、Fのみ。


0

atol()関数を使用するだけです:

#include <stdio.h>
#include <stdlib.h>

int main() 
{
    const char *c = "5";
    int d = atol(c);
    printf("%d\n", d);

}

0

たとえば、数字が'5'ASCIIの場合、2進数0011 0101(53)として表されます。すべての桁には最上位4ビットが0011あり、最下位4ビットはbcdで桁を表します。だからあなたはただ

char cdig = '5';
int dig = cdig & 0xf; // dig contains the number 5

最下位の4ビット、つまり同じ数字を取得します。asm andでは、sub(他の回答のように)の代わりに操作を使用します。


'5'は53(00110101
eyllanesc

@eyllanesc最初は4でした。ありがとう。それを編集しました。
Garmekain

0

charの数字をintに、またはその逆に変換できるヘルパー関数を次に示します。

int toInt(char c) {
    return c - '0';
}

char toChar(int i) {
    return i + '0';
}

-2

関数を使用:配列から整数へのatoi、配列から浮動小数点型へのatof。または

char c = '5';
int b = c - 48;
printf("%d", b);

いくつかの回答がすでにこれをカバーしています。これは、彼らがまだカバーしなかった何も追加しません。
ShadowRanger 2017年

-3

これをint(またはfloatまたはdouble、またはそれ以外に何をしたいか)にキャストし、それを注釈変数に格納します。

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