如何在C中返回长字符的结束数字(特别是当它们是0';s时)

如何在C中返回长字符的结束数字(特别是当它们是0';s时),c,math,C,Math,我一直在处理一个信用卡问题,我在想如何提取一个数字的结尾数字时遇到了困难,例如,用123%10得到3,123%100得到23等,但我遇到的问题是一个数字,比如6310005,其中从%10到10000都只返回5,而我希望它返回5,05005等 long*findDoubles(long-cardNum、int-cardLength、int-startIndex) { 长长度=0; //如果从第二个数字开始,然后在那里计数 如果(startIndex==1) { 长度=地板(卡长度/2); } 其他

我一直在处理一个信用卡问题,我在想如何提取一个数字的结尾数字时遇到了困难,例如,用123%10得到3,123%100得到23等,但我遇到的问题是一个数字,比如6310005,其中从%10到10000都只返回5,而我希望它返回5,05005等

long*findDoubles(long-cardNum、int-cardLength、int-startIndex)
{
长长度=0;
//如果从第二个数字开始,然后在那里计数
如果(startIndex==1)
{
长度=地板(卡长度/2);
}
其他的
{
长度=ceil(卡长度/2);
}
long*doublesArr=malloc(长度);
对于(int i=startIndex;i

如果您有任何帮助,我们将不胜感激,谢谢您在我说这句话之前,请允许我强调您不应将信用卡号存储为整数。

然而。。。关键是,从模运算中得到余数后,需要从初始值中减去余数,然后将初始值除以基数

#include <stdio.h>

int main(void) {
  unsigned long long int CC = 1234123412341234; 
  unsigned long long int temp = CC;
  unsigned short int A[16] = { 0 };
  int i;

  for (i = 0; i < 16; i++) {
    A[15-i] = temp % 10;
    temp = temp - A[15-i];
    temp = temp / 10;
  }

  printf("As an unsigned long long int, the CC number is %llu\n", CC);
  printf("As individual digits in an array, the CC number is ");

  for (i = 0; i < 16; i++) {
    printf("%1d", A[i]);
  }

  printf("\n\n");

  return 0;
}
#包括
内部主(空){
无符号长整型CC=12341234112341234;
无符号长整型温度=CC;
无符号短整数A[16]={0};
int i;
对于(i=0;i<16;i++){
A[15-i]=温度%10;
温度=温度-A[15-i];
温度=温度/10;
}
printf(“作为无符号长整型,CC编号为%llu\n”,CC);
printf(“作为数组中的单个数字,CC编号为”);
对于(i=0;i<16;i++){
printf(“%1d”,A[i]);
}
printf(“\n\n”);
返回0;
}

在我说这些之前,让我强调一下,您不应该将信用卡号存储为整数。

然而。。。关键是,从模运算中得到余数后,需要从初始值中减去余数,然后将初始值除以基数

#include <stdio.h>

int main(void) {
  unsigned long long int CC = 1234123412341234; 
  unsigned long long int temp = CC;
  unsigned short int A[16] = { 0 };
  int i;

  for (i = 0; i < 16; i++) {
    A[15-i] = temp % 10;
    temp = temp - A[15-i];
    temp = temp / 10;
  }

  printf("As an unsigned long long int, the CC number is %llu\n", CC);
  printf("As individual digits in an array, the CC number is ");

  for (i = 0; i < 16; i++) {
    printf("%1d", A[i]);
  }

  printf("\n\n");

  return 0;
}
#包括
内部主(空){
无符号长整型CC=12341234112341234;
无符号长整型温度=CC;
无符号短整数A[16]={0};
int i;
对于(i=0;i<16;i++){
A[15-i]=温度%10;
温度=温度-A[15-i];
温度=温度/10;
}
printf(“作为无符号长整型,CC编号为%llu\n”,CC);
printf(“作为数组中的单个数字,CC编号为”);
对于(i=0;i<16;i++){
printf(“%1d”,A[i]);
}
printf(“\n\n”);
返回0;
}

处理从
startindex开始的部分卡号
作为一个sting来完成时会非常简单。考虑到
所需字符数不超过
21个
(包括符号和nul终止字符),只需一个具有自动存储持续时间的简单缓冲区即可。您可以将缓冲区作为参数传递,只需返回字符串中的
startindex
(通过简单调用
sprintf
)作为
finddoubles
中的字符指针

一个简单的例子是:

#include <stdio.h>

#define MAXSTR 32   /* max chars for long is 21 */

char *finddoubles (long cardnum, int cardlength, int startindex, char *str)
{
    if (!str) {     /* check valid address for str */
        fputs ("error: str unallocated pointer.\n", stderr);
        return NULL;
    }

    /* validate conversion matches cardlength */
    if (sprintf (str, "%ld", cardnum) != cardlength) {
        fputs ("error: conversion not cardlength chars.\n", stderr);
        return NULL;
    }

    return &str[startindex];    /* return requesting substring at index */
}

int main (void) {

    long num = 6310005;   /* example credit card number */
    int len = 7;          /* length */
    char str[MAXSTR];     /* buffer for conversion - avoids allocation */

    for (int i = 0; i < len; i++)   /* output values for all startindexes */
        printf ("start index: %d  indexed card no.: %s\n",
                i, finddoubles (num, len, i, str));
}
有很多方法可以做到这一点。最简单的方法是使用
sprintf
。由于
sprintf
是标准库的一部分,因此无需自行进行转换。仔细检查一下,如果你还有其他问题,请告诉我

编辑16个字符的Cardnum

如果如评论中所述,信用卡号始终为16个字符,那么
sprintf
的简单填充和字段宽度修饰符将确保您通过以下修改对整个卡号进行索引,例如:

    ...
    if (sprintf (str, "%016ld", cardnum) != cardlength) {
    ...
    int len = 16;
    ...
    for (int i = 0; i < len; i++)
        printf ("start index: %2d  indexed card no.: %s\n",
        ...
注意
long
不能在所有系统上容纳16位数字


正如在下面的评论中敏锐地指出的,在传统系统上,例如X86,
值只有32位,并且只能从
-2147483648到2147483647
,并且不能容纳16位。为了补救,最好使用
stdint.h
中定义的精确大小类型,例如
int64\u t
(对于
long
)或更好的
uint64\u t
,因为在这里使用有符号的数字没有什么意义。
inttypes.h
中提供了精确大小类型的相应打印宏

将从
startindex
开始的部分卡号作为一个sting来处理,要简单得多。考虑到
所需字符数不超过
21个
(包括符号和nul终止字符),只需一个具有自动存储持续时间的简单缓冲区即可。您可以将缓冲区作为参数传递,只需返回字符串中的
startindex
(通过简单调用
sprintf
)作为
finddoubles
中的字符指针

一个简单的例子是:

#include <stdio.h>

#define MAXSTR 32   /* max chars for long is 21 */

char *finddoubles (long cardnum, int cardlength, int startindex, char *str)
{
    if (!str) {     /* check valid address for str */
        fputs ("error: str unallocated pointer.\n", stderr);
        return NULL;
    }

    /* validate conversion matches cardlength */
    if (sprintf (str, "%ld", cardnum) != cardlength) {
        fputs ("error: conversion not cardlength chars.\n", stderr);
        return NULL;
    }

    return &str[startindex];    /* return requesting substring at index */
}

int main (void) {

    long num = 6310005;   /* example credit card number */
    int len = 7;          /* length */
    char str[MAXSTR];     /* buffer for conversion - avoids allocation */

    for (int i = 0; i < len; i++)   /* output values for all startindexes */
        printf ("start index: %d  indexed card no.: %s\n",
                i, finddoubles (num, len, i, str));
}
有很多方法可以做到这一点。最简单的方法是使用
sprintf
。由于
sprintf
是标准库的一部分,因此无需自行进行转换。仔细检查一下,如果你还有其他问题,请告诉我

编辑16个字符的Cardnum

如果如评论中所述,信用卡号始终为16个字符,那么
sprintf
的简单填充和字段宽度修饰符将确保您通过以下修改对整个卡号进行索引,例如:

    ...
    if (sprintf (str, "%016ld", cardnum) != cardlength) {
    ...
    int len = 16;
    ...
    for (int i = 0; i < len; i++)
        printf ("start index: %2d  indexed card no.: %s\n",
        ...
注意
long
不能在所有系统上容纳16位数字

正如在下面的评论中敏锐地指出的,在传统系统上,例如X86,
值只有32位,并且只能从
-2147483648到2147483647
,并且不能容纳16位。为了补救,最好使用
stdint.h
中定义的精确大小类型,例如
int64\u t
(对于您的
long
)或更好的
uint64\u t
,因为使用带符号的数字不会带来什么好处
#include <stdio.h>

unsigned long long pow10_ull(unsigned y) {
  unsigned long long z = 1;
  unsigned long long base = 10;
  while (y) {
    if (y % 2) {
      z *= base;
    }
    y /= 2;
    base *= base;
  }
  return z;
}

unsigned long long endDigits(unsigned long long cardNum, int endLength) {
  return cardNum % pow10_ull(endLength);
}

void printEndDigits(unsigned long long cardNum, int cardLength,
    int startIndex) {
  int endLength = cardLength - startIndex;
  printf("%.*llu\n", endLength, endDigits(cardNum, endLength));
}

int main() {
  printEndDigits(378282246310005, 15, 1);
  printEndDigits(378282246310005, 15, 11);
  return 0;
}
78282246310005
0005