Вы можете использовать strcspn
, чтобы найти конец массива char
в условии while
, вы можете вернуть размер массива char
, пока он не найдет '\0'
( или '\n'
, поскольку вы, похоже, не удаляете его из массива), затем вы можете использовать это, чтобы установить минимальный размер для ввода.
#include <string.h>
//...
do{
//...
while (strcspn(buf, "") < 14); //less than 13 chars will repeat the cycle
//...
Вы также можете удалить '\n'
от buf
, в этом случае вы можете использовать strlen
:
//...
do{
fgets(buf, 17, stdin);
buf[strcspn(buf, "\n")] = '\0';
while (strlen(buf) < 13); //by removing '\n' you can use strlen
//...
Максимальный размер buf
будет 16
, поскольку вы ограничите размер fgets
до 17
, поэтому он будет хранить 16
символов плюс нулевой терминатор, вы можете уменьшить размер вашего массива до 17
, так как элемент 18th
бесполезен.
Также имейте в виду, что long
не всегда 8 байтов, https://en.wikibooks.org/wiki/C_Programming/limits.h
При этом существует проблема наследования кода, он потребляет все, например, c символов, пробелов и т. д. c. , поэтому, если у вас есть ввод 1234 1234 1234 1234
, только 1234
будет преобразовано в strtol
.
В приведенном ниже примере я удаляю все, что не является ди git и сохраняю все остальные ваши спецификации:
Рабочий образец
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
int main()
{
long long cn; //long long is never smaller than 8 bytes
int i, c;
char buf[17];
do {
i = 0;
printf("card number please: ");
while ((c = fgetc(stdin)) != '\n' && c != EOF && strlen(buf) < 17) //max size 16
{
if (isdigit(c)) //only digits
buf[i++] = c;
}
buf[i] = '\0';
} while (strlen(buf) < 13); //min size 13
cn = strtoll(buf, NULL, 10); //strtoll for long long
printf("%lld\n", cn);
}