Обрабатывать частичный номер карты, начинающийся с startindex
, немного проще, если делать это как жало.Учитывая, что для long
может потребоваться не более 21-chars
(включая знак и nul-terminating символ), все, что требуется, - это простой буфер с автоматической продолжительностью хранения.Вы можете передать буфер в качестве параметра и просто вернуть 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
.