C语言 从整个整数中获取每个单独的数字

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3118490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:44:33  来源:igfitidea点击:

Getting each individual digit from a whole integer

cbitwise-operators

提问by Johannes Jensen

Let's say I have an integer called 'score', that looks like this:

假设我有一个名为“score”的整数,它看起来像这样:

int score = 1529587;

Now what I want to do is get each digit 1, 5, 2, 9, 5, 8, 7 from the score using bitwise operators(See below edit note).

现在我想要做的是使用按位运算符从分数中获取每个数字 1, 5, 2, 9, 5, 8, 7 (见下面的编辑说明)。

I'm pretty sure this can be done since I've once used a similar method to extract the red green and blue values from a hexadecimal colour value.

我很确定这是可以做到的,因为我曾经使用过类似的方法从十六进制颜色值中提取红色绿色和蓝色值。

How would I do this?

我该怎么做?

Edit
It doesn't necessarily have to be bitwise operators, I just thought it'd be simpler that way.

编辑
它不一定是按位运算符,我只是认为那样会更简单。

回答by Martin B

You use the modulo operator:

您使用模运算符:

while(score)
{
    printf("%d\n", score % 10);
    score /= 10;
}

Note that this will give you the digits in reverse order (i.e. least significant digit first). If you want the most significant digit first, you'll have to store the digits in an array, then read them out in reverse order.

请注意,这将以相反的顺序为您提供数字(即最低有效数字在前)。如果您首先想要最重要的数字,则必须将数字存储在数组中,然后以相反的顺序读出它们。

回答by valdo

Agree with previous answers.

同意之前的回答。

A little correction: There's a better way to print the decimal digits from left to right, without allocating extra buffer. In addition you may want to display a zero characeter if the scoreis 0 (the loop suggested in the previous answers won't print anythng).

一点更正:有一种更好的方法可以从左到右打印十进制数字,而无需分配额外的缓冲区。此外,如果score为 0,您可能希望显示零字符(前面答案中建议的循环不会打印任何内容)。

This demands an additional pass:

这需要额外的通行证:

int div;
for (div = 1; div <= score; div *= 10)
    ;

do
{
    div /= 10;
    printf("%d\n", score / div);
    score %= div;
} while (score);

回答by David M

RGB values fall nicely on bit boundaries; decimal digits don't. I don't think there's an easy way to do this using bitwise operators at all. You'd need to use decimal operators like modulo 10 (% 10).

RGB 值很好地落在位边界上;十进制数字没有。我不认为有一种简单的方法可以使用按位运算符来做到这一点。您需要使用像模 10 (% 10) 这样的十进制运算符。

回答by R.. GitHub STOP HELPING ICE

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.

不要重新发明轮子。C 有 sprintf 是有原因的。由于您的变量称为分数,我猜这适用于您计划使用分数的各个数字将数字字形显示为图像的游戏。在这种情况下, sprintf 具有方便的格式修饰符,可以让您零填充、空格填充等将分数设置为固定宽度,您可能想要使用它。

回答by Britton Kerin

This solution gives correct results over the entire range [0,UINT_MAX] without requiring digits to be buffered.

此解决方案可在整个范围 [0,UINT_MAX] 内提供正确结果,而无需缓冲数字。

It also works for wider types or signed types (with positive values) with appropriate type changes.

它也适用于具有适当类型更改的更宽类型或带符号类型(具有正值)。

This kind of approach is particularly useful on tiny environments (e.g. Arduino bootloader) because it doesn't end up pulling in all the printf() bloat (when printf() isn't used for demo output) and uses very little RAM. You can get a look at value just by blinking a single led :)

这种方法在微型环境(例如 Arduino 引导加载程序)上特别有用,因为它最终不会导致所有 printf() 膨胀(当 printf() 不用于演示输出时)并且使用很少的 RAM。您只需闪烁一个 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;
}

回答by Esann

//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(score>0)
{
    div /= 10;
    printf("%d\n`enter code here`", score / div);
    score %= div;
}

回答by RohitK

#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);}

回答by PADYMKO

Usually, this problem resolve with using the modulo of a number in a loop or convert a number to a string. For convert a number to a string, you may can use the function itoa, so considering the variant with the modulo of a number in a loop.

通常,此问题通过在循环中使用数字的模或将数字转换为字符串来解决。要将数字转换为字符串,您可以使用函数itoa,因此考虑循环中数字模数的变体。



Content of a file get_digits.c

文件内容 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);
}


Demo with the GNU GCC

使用 GNU GCC 进行演示

$~/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]

Demo with the LLVM/Clang

使用 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]


Testing environment

测试环境

$~/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