我一直在解决信用卡问题,但在弄清楚如何提取数字的结尾数字时遇到了麻烦,例如,执行123%10可获得3,123%100可获得23等。但是我遇到的问题是一个数字,例如6310005,其中%10到10000全部返回5,而我希望它返回5,05,005等。Here is a link to the output of findDoubles(378282246310005,15,1)
long* findDoubles(long cardNum, int cardLength, int startIndex)
{
long length = 0;
// if starting at the second number, and counting there on
if(startIndex == 1 )
{
length = floor(cardLength/2);
}
else
{
length = ceil(cardLength/2);
}
long *doublesArr = malloc(length);
for (int i = startIndex; i < length; i++)
{
doublesArr[i] = cardNum % (long)pow(10,i);
printf("\ndoublesArr[%i] = %lu",i, doublesArr[i]);
}
return doublesArr;
}
任何帮助将不胜感激,谢谢
答案 0 :(得分:2)
在我这样说之前,让我强调一下,您 不应将信用卡号存储为整数。
但是...关键是,从模运算中得到余数之后,您需要从初始值中减去它,然后将初始值除以基数。
#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;
}
答案 1 :(得分:1)
处理以startindex
开头的部分卡号要容易得多。假设long
最多只需要21-chars
(包括符号和 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));
}
(注意:您只需将返回值分配给字符指针(例如char *p = finddoubles (num, len, i, str);
即可使用,而不是立即打印该值)
使用/输出示例
$ ./bin/cardnumidx
start index: 0 indexed card no.: 6310005
start index: 1 indexed card no.: 310005
start index: 2 indexed card no.: 10005
start index: 3 indexed card no.: 0005
start index: 4 indexed card no.: 005
start index: 5 indexed card no.: 05
start index: 6 indexed card no.: 5
有很多方法可以做到这一点。最简单的是使用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",
...
使用/输出示例
$ ./bin/cardnumidx
start index: 0 indexed card no.: 0000000006310005
start index: 1 indexed card no.: 000000006310005
start index: 2 indexed card no.: 00000006310005
start index: 3 indexed card no.: 0000006310005
start index: 4 indexed card no.: 000006310005
start index: 5 indexed card no.: 00006310005
start index: 6 indexed card no.: 0006310005
start index: 7 indexed card no.: 006310005
start index: 8 indexed card no.: 06310005
start index: 9 indexed card no.: 6310005
start index: 10 indexed card no.: 310005
start index: 11 indexed card no.: 10005
start index: 12 indexed card no.: 0005
start index: 13 indexed card no.: 005
start index: 14 indexed card no.: 05
start index: 15 indexed card no.: 5
注意long
不能在所有系统上都包含16位数字
如@chqrlie在以下评论中针对旧版系统(例如X86中,long
的值只有32位,只能从-2147483648 to 2147483647
开始,并且不能保存16位。为了解决这个问题,最好使用stdint.h
中定义的精确尺寸类型,例如int64_t
(对于您的long
)或更佳的uint64_t
,例如使用带符号数字在这里毫无意义。 inttypes.h
中提供了用于精确尺寸类型的相应打印宏。
答案 2 :(得分:0)
返回
long
的结束数字
这只是long
的“ mod”(按10的幂)。
要在打印中保留前导零,请将".*"
或 precision 用作printf()
的一部分以直接输出,或使用sprintf()
保存到字符串。
由于抄送号码通常超过10位数字,因此最好使用可以容纳long
的更宽的类型,这可能是不够的。 unsigned long long
可以处理所有19位数字-至少。
#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