Вы можете использовать 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
При этом существует проблема наследования кода, он потребляет все, афабетические символы, пробелы и т. д., поэтому, если у вас есть ввод 1234 1234 1234 1234
, только 1234
будет преобразован strtol
.
В приведенном ниже примере я удаляю все, что не является цифрой, и сохраняю все остальные характеристики:
Используемый пример
#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);
}
person
anastaciu
schedule
13.04.2020
fgets
сохраняет символ новой строки'\n'
в конце строки. Он также читает максимум на один символ меньше указанного, усекая ввод, если он не подходит. Это означает, что для короткого номера символ после номера будет'\n'
, а не'\0'
. Исключение составляет шестнадцатизначное число без пробелов: здесь'\n'
не подходит и не включается в строку. - person M Oehm   schedule 13.04.2020fgets
, включает в себя место для нулевого терминатора, так что вы могли быfgets(buf, 18, stdin)
или, может быть, даже лучшеfgets(buf, sizeof(buf), stdin)
. Вы также можете сделать буфер намного больше и принимать дополнительные пробелы и дефисы, потому что люди склонны форматировать свои номера копий в четырехзначные фрагменты.) - person M Oehm   schedule 13.04.2020strtol
для проверки того, является ли ввод допустимым числом, вы должны явно использовать основание 10. В противном случае вы можете быть удивлены, если у вас есть номер копии с начальным нулем и с восьмерками и девятками в нем... - person M Oehm   schedule 13.04.2020