Проверьте, является ли ввод целым типом в C
Уловка заключается в том, что я не могу использовать atoi или любую другую функцию (я уверен, что мы должны полагаться на математические операции).
int num; scanf("%d",&num); if(/* num is not integer */) { printf("enter integer"); return; }
Я пробовал:
(num*2)/2 == num num%1==0 if(scanf("%d",&num)!=1)
но никто из них не работал.
- 09 не распознается, где 9 признано
- Как проверить, соответствует ли строка int, не используя try / except?
- Что такое целочисленное переполнение в R и как это может произойти?
- 128-битное целое число на cuda?
- Каково максимальное значение для int32?
Есть идеи?
- Почему Java не поддерживает unsigned ints?
- чтение двух целых чисел в одной строке с использованием C #
- Как проверить, четное или нечетное целое?
- Задача производительности C ++: целое число для преобразования std :: string
- Что произойдет, если я присвою отрицательное значение неподписанной переменной?
- Как передать объект в int
- Печать int в двоичном представлении с использованием C
num
всегда будет содержать целое число, потому что это int
. Реальная проблема с вашим кодом заключается в том, что вы не проверяете возвращаемое значение scanf
. scanf
возвращает количество успешно прочитанных элементов, поэтому в этом случае он должен возвращать 1 для допустимых значений. Если нет, было введено недопустимое целочисленное значение, и переменная num
, вероятно, не была изменена (т. Е. Все еще имеет произвольное значение, потому что вы ее не инициализировали).
По состоянию на ваш комментарий вы хотите разрешить пользователю вводить целое число, за которым следует ключ ввода. К сожалению, это не может быть просто достигнуто scanf("%d\n")
, но вот трюк для этого:
int num; char term; if(scanf("%d%c", &num, &term) != 2 || term != '\n') printf("failure\n"); else printf("valid integer followed by enter key\n");
Сначала вы должны прочитать свой ввод как строку, затем проанализировать строку, чтобы увидеть, содержит ли она действительные числовые символы. Если это так, вы можете преобразовать его в целое.
char s[MAX_LINE]; valid = FALSE; fgets(s, sizeof(s), stdin); len = strlen(s); while (len > 0 && isspace(s[len - 1])) len--; // strip trailing newline or other white space if (len > 0) { valid = TRUE; for (i = 0; i < len; ++i) { if (!isdigit(s[i])) { valid = FALSE; break; } } }
Существует несколько проблем с использованием scanf
с помощью спецификатора преобразования %d
:
-
Если входная строка начинается с действительного целого числа (например, «12abc»), тогда «12» будет считаться из входного streamа и преобразовываться и присваиваться
num
, аscanf
будет возвращать 1, поэтому вы укажете успех, когда вы (вероятно) не должен; -
Если входная строка не начинается с цифры,
scanf
не будет считывать никаких символов из входного streamа,num
не будет изменен, а возвращаемое значение будет 0; -
Вы не указываете, нужно ли обрабатывать не десятичные форматы, но это не сработает, если вам нужно обрабатывать целочисленные значения в восьмеричных или шестнадцатеричных форматах (0x1a). Спецификатор преобразования
%i
обрабатывает десятичные, восьмеричные и шестнадцатеричные форматы, но у вас все еще есть первые две проблемы.
Прежде всего, вам нужно будет прочитать ввод как строку (желательно с помощью fgets
). Если вам запрещено использовать atoi
, вам, вероятно, также не разрешается использовать strtol
. Поэтому вам нужно будет изучить каждый символ в строке. Безопасный способ проверить значения цифр – использовать функцию isdigit
library (есть также функции isodigit
и isxdigit
для проверки восьмеричных и шестнадцатеричных цифр соответственно), например
while (*input && isdigit(*input)) input++;
(если вам даже не разрешено использовать isodigit
, isodigit
или isxdigit
, а затем удалите своего учителя / профессора, чтобы сделать назначение сложнее, чем это действительно должно быть).
Если вам нужно иметь возможность обрабатывать восьмеричные или шестнадцатеричные форматы, это становится немного сложнее. Соглашение C для восьмеричных форматов имеет ведущую цифру 0
а для шестнадцатеричных форматов – ведущее 0x
. Итак, если первый символ без пробелов равен 0, вы должны проверить следующий символ, прежде чем сможете узнать, какой формат не десятичного числа использовать.
Основной план
- Если первый символ без пробелов не является символом ‘-‘, ‘+’, ‘0’ или отличным от нуля десятичным значком, то это не допустимая целая строка;
- Если первым символом без пробела является «-», то это отрицательное значение, иначе мы принимаем положительное значение;
- Если первый символ «+», то это положительное значение;
- Если первый символ без пробелов и знаков без знака представляет собой ненулевую десятичную цифру, тогда вход находится в десятичном формате, и вы будете использовать
isdigit
для проверки оставшихся символов; - Если первый символ без пробелов и символов без знака равен ‘0’, то вход будет либо в восьмеричном, либо в шестнадцатеричном формате;
- Если первый символ без пробела и не знака был «0», а следующий символ – цифрой от «0» до «7», тогда вход будет в восьмеричном формате, и вы будете использовать
isodigit
для проверки оставшихся символов ; - Если первый символ без пробела и не знака равен 0, а второй символ –
x
илиX
, то вход в шестнадцатеричном формате, и вы будете использоватьisxdigit
для проверки оставшихся символов; - Если какой-либо из оставшихся символов не удовлетворяет указанной выше функции проверки, то это не допустимая целая строка.
Сначала спросите себя, как бы вы ожидали, что этот код НЕ вернет целое число:
int num; scanf("%d",&num);
Вы указали переменную как целое число, а затем scanf
, но только для целого числа ( %d
).
Что еще может это содержать?
Я просмотрел все вышеприведенные данные, что было очень полезно, и сделал функцию, которая была подходящей для моего собственного приложения. Функция действительно только оценивает, что вход пользователя не является «0», но он был достаточно хорош для моей цели. Надеюсь это поможет!
#include int iFunctErrorCheck(int iLowerBound, int iUpperBound){ int iUserInput=0; while (iUserInput==0){ scanf("%i", &iUserInput); if (iUserInput==0){ printf("Please enter an integer (%i-%i).\n", iLowerBound, iUpperBound); getchar(); } if ((iUserInput!=0) && (iUserInputiUpperBound)){ printf("Please make a valid selection (%i-%i).\n", iLowerBound, iUpperBound); iUserInput=0; } } return iUserInput; }
Попробуй это…
#include int main (void) { float a; int q; printf("\nInsert number\t"); scanf("%f",&a); q=(int)a; ++q; if((q - a) != 1) printf("\nThe number is not an integer\n\n"); else printf("\nThe number is an integer\n\n"); return 0; }
Это более удобный для пользователя, я думаю:
#include /* This program checks if the entered input is an integer * or provides an option for the user to re-enter. */ int getint() { int x; char c; printf("\nEnter an integer (say -1 or 26 or so ): "); while( scanf("%d",&x) != 1 ) { c=getchar(); printf("You have entered "); putchar(c); printf(" in the input which is not an integer"); while ( getchar() != '\n' ) ; //wasting the buffer till the next new line printf("\nEnter an integer (say -1 or 26 or so ): "); } return x; } int main(void) { int x; x=getint(); printf("Main Function =>\n"); printf("Integer : %d\n",x); return 0; }
Я разработал эту логику, используя полученные и удаленные от проверки проблемы:
void readValidateInput() { char str[10] = { '\0' }; readStdin: fgets(str, 10, stdin); //printf("fgets is returning %s\n", str); int numerical = 1; int i = 0; for (i = 0; i < 10; i++) { //printf("Digit at str[%d] is %c\n", i, str[i]); //printf("numerical = %d\n", numerical); if (isdigit(str[i]) == 0) { if (str[i] == '\n')break; numerical = 0; //printf("numerical changed= %d\n", numerical); break; } } if (!numerical) { printf("This is not a valid number of tasks, you need to enter at least 1 task\n"); goto readStdin; } else if (str[i] == '\n') { str[i] = '\0'; numOfTasks = atoi(str); //printf("Captured Number of tasks from stdin is %d\n", numOfTasks); } }
printf("type a number "); int converted = scanf("%d", &a); printf("\n"); if( converted == 0) { printf("enter integer"); system("PAUSE \n"); return 0; }
scanf () возвращает количество спецификаторов формата, которые соответствуют, поэтому возвратит ноль, если введенный текст не может быть интерпретирован как десятичное целое число
У меня была такая же проблема, в конце концов выяснилось, что делать:
#include #include int main () { int x; float check; reprocess: printf ("enter a integer number:"); scanf ("%f", &check); x=check; if (x==check) printf("\nYour number is %d", x); else { printf("\nThis is not an integer number, please insert an integer!\n\n"); goto reprocess; } _getch(); return 0; }
Я искал более простое решение, используя только циклы и операторы if, и это то, что я придумал. Программа также работает с отрицательными целыми числами и правильно отклоняет любые смешанные входы, которые могут содержать как целые числа, так и другие символы.
#include #include // Used for atoi() function #include // Used for strlen() function #define TRUE 1 #define FALSE 0 int main(void) { char n[10]; // Limits characters to the equivalent of the 32 bits integers limit (10 digits) int intTest; printf("Give me an int: "); do { scanf(" %s", n); intTest = TRUE; // Sets the default for the integer test variable to TRUE int i = 0, l = strlen(n); if (n[0] == '-') // Tests for the negative sign to correctly handle negative integer values i++; while (i < l) { if (n[i] < '0' || n[i] > '9') // Tests the string characters for non-integer values { intTest = FALSE; // Changes intTest variable from TRUE to FALSE and breaks the loop early break; } i++; } if (intTest == TRUE) printf("%i\n", atoi(n)); // Converts the string to an integer and prints the integer value else printf("Retry: "); // Prints "Retry:" if tested FALSE } while (intTest == FALSE); // Continues to ask the user to input a valid integer value return 0; }
Этот метод работает для всего (целые числа и даже удваивает), кроме нуля (он называет его недействительным):
Цикл while предназначен только для повторного ввода пользователем. В основном, он проверяет, является ли целое число x / x = 1. Если он делает (как и для числа), его целое число / double. Если это не так, очевидно, это не так. Однако Zero терпит неудачу.
#include #include void main () { double x; int notDouble; int true = 1; while(true) { printf("Input an integer: \n"); scanf("%lf", &x); if (x/x != 1) { notDouble = 1; fflush(stdin); } if (notDouble != 1) { printf("Input is valid\n"); } else { printf("Input is invalid\n"); } notDouble = 0; } }
Я нашел способ проверить, является ли введенный ввод целым или не использует функцию atoi ().
Прочитайте ввод как строку и используйте функцию atoi (), чтобы преобразовать строку в целое число.
Функция atoi () возвращает целое число, если входная строка содержит целое число, иначе она вернет 0. Вы можете проверить возвращаемое значение функции atoi (), чтобы узнать, является ли введенный ввод целым или нет.
Есть гораздо больше функций для преобразования строки в long, double и т. Д., Проверьте стандартную библиотеку «stdlib.h» для большего.
Примечание. Он работает только для ненулевых чисел.
#include #include int main() { char *string; int number; printf("Enter a number :"); scanf("%s", string); number = atoi(string); if(number != 0) printf("The number is %d\n", number); else printf("Not a number !!!\n"); return 0; }