'score'という整数があり、次のようになっているとします。
int score = 1529587;
ここで私がやりたいのは、ビット演算子を使用してスコアから各桁1、5、2、9、5、8、7を取得することです(以下の編集ノートを参照)。
私はかつて同様の方法を使用して16進数の色の値から赤、緑、青の値を抽出したことがあるので、これができると確信しています。
どうすればいいですか?
編集
必ずしもビット演算子である必要はありません。そうすればもっと簡単になると思いました。
'score'という整数があり、次のようになっているとします。
int score = 1529587;
ここで私がやりたいのは、ビット演算子を使用してスコアから各桁1、5、2、9、5、8、7を取得することです(以下の編集ノートを参照)。
私はかつて同様の方法を使用して16進数の色の値から赤、緑、青の値を抽出したことがあるので、これができると確信しています。
どうすればいいですか?
編集
必ずしもビット演算子である必要はありません。そうすればもっと簡単になると思いました。
モジュロ演算子を使用します。
while(score)
{
printf("%d\n", score % 10);
score /= 10;
}
これにより、数字が逆の順序で表示されることに注意してください(つまり、最下位桁が最初になります)。最上位桁を最初に使用する場合は、桁を配列に格納してから、逆の順序で読み取る必要があります。
RGB値はビット境界にうまく収まります。10進数はそうではありません。ビット演算子を使用してこれを行う簡単な方法はまったくないと思います。モジュロ10(%10)のような10進演算子を使用する必要があります。
Don't reinvent the wheel. C has sprintf
for a reason.
Since your variable is called score, I'm guessing this is for a game where you're planning to use the individual digits of the score to display the numeral glyphs as images. In this case, sprintf
has convenient format modifiers that will let you zero-pad, space-pad, etc. the score to a fixed width, which you may want to use.
以前の回答に同意します。
少し修正:余分なバッファを割り当てずに、左から右に10進数を印刷するためのより良い方法があります。さらに、が0の場合は、ゼロの文字を表示することをお勧めしますscore
(前の回答で提案されたループは何も出力しません)。
これには追加のパスが必要です。
int div;
for (div = 1; div <= score; div *= 10)
;
do
{
div /= 10;
printf("%d\n", score / div);
score %= div;
} while (score);
このソリューションは、数字をバッファリングする必要なしに、範囲[0、UINT_MAX]全体にわたって正しい結果を提供します。
また、適切なタイプの変更を伴う、より広いタイプまたは符号付きタイプ(正の値)でも機能します。
この種のアプローチは、(printf()がデモ出力に使用されていない場合)すべてのprintf()の肥大化を引き起こさず、RAMをほとんど使用しないため、小さな環境(Arduinoブートローダーなど)で特に役立ちます。1つのLEDを点滅させるだけで値を確認できます:)
#include <limits.h>
#include <stdio.h>
int
main (void)
{
unsigned int score = 42; // Works for score in [0, UINT_MAX]
printf ("score via printf: %u\n", score); // For validation
printf ("score digit by digit: ");
unsigned int div = 1;
unsigned int digit_count = 1;
while ( div <= score / 10 ) {
digit_count++;
div *= 10;
}
while ( digit_count > 0 ) {
printf ("%d", score / div);
score %= div;
div /= 10;
digit_count--;
}
printf ("\n");
return 0;
}
通常、この問題は、ループ内の数値のモジュロを使用するか、数値を文字列に変換することで解決します。数値を文字列に変換するには、関数itoaを使用できるため、ループ内の数値のモジュロを使用したバリアントを検討します。
ファイルの内容get_digits.c
$ cat get_digits.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
// return a length of integer
unsigned long int get_number_count_digits(long int number);
// get digits from an integer number into an array
int number_get_digits(long int number, int **digits, unsigned int *len);
// for demo features
void demo_number_get_digits(long int number);
int
main()
{
demo_number_get_digits(-9999999999999);
demo_number_get_digits(-10000000000);
demo_number_get_digits(-1000);
demo_number_get_digits(-9);
demo_number_get_digits(0);
demo_number_get_digits(9);
demo_number_get_digits(1000);
demo_number_get_digits(10000000000);
demo_number_get_digits(9999999999999);
return EXIT_SUCCESS;
}
unsigned long int
get_number_count_digits(long int number)
{
if (number < 0)
number = llabs(number);
else if (number == 0)
return 1;
if (number < 999999999999997)
return floor(log10(number)) + 1;
unsigned long int count = 0;
while (number > 0) {
++count;
number /= 10;
}
return count;
}
int
number_get_digits(long int number, int **digits, unsigned int *len)
{
number = labs(number);
// termination count digits and size of a array as well as
*len = get_number_count_digits(number);
*digits = realloc(*digits, *len * sizeof(int));
// fill up the array
unsigned int index = 0;
while (number > 0) {
(*digits)[index] = (int)(number % 10);
number /= 10;
++index;
}
// reverse the array
unsigned long int i = 0, half_len = (*len / 2);
int swap;
while (i < half_len) {
swap = (*digits)[i];
(*digits)[i] = (*digits)[*len - i - 1];
(*digits)[*len - i - 1] = swap;
++i;
}
return 0;
}
void
demo_number_get_digits(long int number)
{
int *digits;
unsigned int len;
digits = malloc(sizeof(int));
number_get_digits(number, &digits, &len);
printf("%ld --> [", number);
for (unsigned int i = 0; i < len; ++i) {
if (i == len - 1)
printf("%d", digits[i]);
else
printf("%d, ", digits[i]);
}
printf("]\n");
free(digits);
}
GNUGCCを使用したデモ
$~/Downloads/temp$ cc -Wall -Wextra -std=c11 -o run get_digits.c -lm
$~/Downloads/temp$ ./run
-9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
-10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-1000 --> [1, 0, 0, 0]
-9 --> [9]
0 --> [0]
9 --> [9]
1000 --> [1, 0, 0, 0]
10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
LLVM/Clangを使用したデモ
$~/Downloads/temp$ rm run
$~/Downloads/temp$ clang -std=c11 -Wall -Wextra get_digits.c -o run -lm
setivolkylany$~/Downloads/temp$ ./run
-9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
-10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
-1000 --> [1, 0, 0, 0]
-9 --> [9]
0 --> [0]
9 --> [9]
1000 --> [1, 0, 0, 0]
10000000000 --> [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
9999999999999 --> [9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9]
テスト環境
$~/Downloads/temp$ cc --version | head -n 1
cc (Debian 4.9.2-10) 4.9.2
$~/Downloads/temp$ clang --version
Debian clang version 3.5.0-10 (tags/RELEASE_350/final) (based on LLVM 3.5.0)
Target: x86_64-pc-linux-gnu
Thread model: posix
//this can be easily understandable for beginners
int score=12344534;
int div;
for (div = 1; div <= score; div *= 10)
{
}
/*for (div = 1; div <= score; div *= 10); for loop with semicolon or empty body is same*/
while(div>1)
{
div /= 10;
printf("%d\n`enter code here`", score / div);
score %= div;
}
#include<stdio.h>
int main() {
int num; //given integer
int reminder;
int rev=0; //To reverse the given integer
int count=1;
printf("Enter the integer:");
scanf("%i",&num);
/*First while loop will reverse the number*/
while(num!=0)
{
reminder=num%10;
rev=rev*10+reminder;
num/=10;
}
/*Second while loop will give the number from left to right*/
while(rev!=0)
{
reminder=rev%10;
printf("The %d digit is %d\n",count, reminder);
rev/=10;
count++; //to give the number from left to right
}
return (EXIT_SUCCESS);}
まず、を使用して整数を文字列に変換しsprintf
、次にその要素、つまり。を使用して必要な処理を行いますchars
。unsigned
スコアを想定する:
unsigned int score = 1529587, i;
char stringScore [11] = { 0 };
sprintf( stringScore, "%d, score );
for( i=0; i<strlen(stringScore); i++ )
printf( "%c\n", stringScore[i] );
方法に注意してください:
stringScore
プラットフォームでののサイズが4バイトであると仮定すると、は11文字の長さであるint
ため、最大整数は10桁の長さです。11つ目は、文字列ターミネータ文字用'\0'
です。sprintf
あなたのためにすべての仕事をします数字だけが含まれていると確信しているのでstringScore
、変換は本当に簡単です。が数字を含む文字の場合dig
、対応する整数は次の方法で取得できます。
int intDigit = dig - '0';
私はこのソリューションを作成しました-代わりに整数を読み取り、文字列(Cのchar配列)を読み取り、次にfor bucleを使用して書き込み、コードは桁の合計も書き込みます
// #include<string.h>
scanf("%s", n);
int total = 0;
for (int i = 0; i< strlen(n); i++){
printf("%c", n[i]);
total += (int)(n[i]) -48;
}
printf("%d", total);