「strtoll」関数で文字列を符号付き長整数に変換する方法:初心者向けチュートリアル
long long strtoll(const char *str, char **endptr, int base);
引数
base
: 文字列を解釈する基数。有効な基数は 2 から 36 まで、または 0 です。0 を指定すると、文字列の先頭から始まる最長の有効な数値部分に基づいて基数が自動的に判別されます。endptr
: 変換後の文字列のポインタを格納する変数へのポインタ。変換が成功した場合、endptr
は変換後の文字列の最初の文字を指すように設定されます。endptr
がNULL
の場合、この引数は使用されません。str
: 変換対象の文字列を含むポインタ
戻り値
変換に成功した場合、strtoll
関数は変換された符号付き長整数値を返します。変換に失敗した場合、0 を返します。
エラー処理
strtoll
関数は、変換に失敗した場合、errno
変数にエラーコードを設定します。考えられるエラーコードは以下の通りです。
EINVAL
: 無効な基数が指定された場合ERANGE
: 変換結果が符号付き長整数の表現範囲外である場合
例
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "123456789";
char *endptr;
long long num;
num = strtoll(str, &endptr, 10);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%lld\n", num);
}
return 0;
}
この例では、文字列 "123456789" を 10 進数として解釈し、符号付き長整数に変換しています。変換に成功すると、変換された値がコンソールに出力されます。
strtoll
関数は、文字列の先頭に "0" がある場合、8 進数として解釈します。strtoll
関数は、文字列の先頭に "0x" または "0X" がある場合、16 進数として解釈します。strtoll
関数は、文字列の先頭に符号 (+/-) がある場合、符号付き長整数として解釈します。strtoll
関数は、strtol
関数と同様に、文字列の先頭の空白文字を無視します。
例 1:10 進数の文字列を符号付き長整数に変換する
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "123456789";
char *endptr;
long long num;
num = strtoll(str, &endptr, 10);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%lld\n", num);
}
return 0;
}
例 2:16 進数の文字列を符号付き長整数に変換する
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "0xABCDEF";
char *endptr;
long long num;
num = strtoll(str, &endptr, 16);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%lld\n", num);
}
return 0;
}
この例では、文字列 "0xABCDEF" を 16 進数として解釈し、符号付き長整数に変換しています。変換に成功すると、変換された値がコンソールに出力されます。
例 3:8 進数の文字列を符号付き長整数に変換する
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "01234567";
char *endptr;
long long num;
num = strtoll(str, &endptr, 8);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%lld\n", num);
}
return 0;
}
例 4:文字列の先頭に符号が付いている場合の変換
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "-123456789";
char *endptr;
long long num;
num = strtoll(str, &endptr, 10);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%lld\n", num);
}
return 0;
}
この例では、文字列 "-123456789" を 10 進数として解釈し、符号付き長整数に変換しています。変換に成功すると、変換された値がコンソールに出力されます。符号が - のため、変換された値は負の数になります。
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "abc123";
char *endptr;
long long num;
num = strtoll(str, &endptr, 10);
if (num == 0) {
if (errno == ERANGE) {
printf("変換結果が符号付き長整数の表現範囲外です。\n");
} else if (errno == EINVAL) {
printf("無効な基数が指定されました。\n");
} else {
printf("その他のエラーが発生しました。\n");
}
} else {
printf("%lld\n", num);
}
return 0;
}
strtol 関数
strtol
関数は、strtoll
関数と似ていますが、変換結果が long int
型になります。符号付き長整数の表現範囲を超える値を扱う場合は、strtoll
関数ではなく strtol
関数を使用する必要があります。
long int strtol(const char *nptr, char **endptr, int base);
例
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "123456789";
char *endptr;
long int num;
num = strtol(str, &endptr, 10);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%ld\n", num);
}
return 0;
}
atoi 関数
atoi
関数は、文字列を int
型に変換します。符号付き長整数に変換する場合は、変換結果を (long long)atoi(str)
のように明示的に型変換する必要があります。ただし、atoi
関数は、符号付き長整数の表現範囲を超える値を扱うことができないため、注意が必要です。
int atoi(const char *nptr);
例
#include <stdio.h>
#include <stdlib.h>
int main() {
char str[] = "123456789";
long long num;
num = (long long)atoi(str);
if (num == 0) {
printf("変換に失敗しました。\n");
} else {
printf("%lld\n", num);
}
return 0;
}
手動解析
上記の関数はいずれも使用できない場合、文字列を自分で解析して符号付き長整数に変換することができます。この方法は柔軟性がありますが、複雑でエラーが発生しやすいという欠点があります。
例
long long my_strtol(const char *str, int base) {
long long result = 0;
int sign = 1;
int i = 0;
if (str[i] == '+' || str[i] == '-') {
if (str[i] == '-') {
sign = -1;
}
i++;
}
while (str[i] != '\0') {
int digit = str[i] - '0';
if (digit < 0 || digit > base - 1) {
return 0;
}
result = result * base + digit;
i++;
}
return result * sign;
}
カスタム関数
上記の代替方法のいずれもニーズに合わない場合は、独自の関数を作成することができます。この方法は、特定の要件に合わせた柔軟なソリューションを提供できますが、開発とテストに時間がかかります。