#c #scanf
#c #scanf
Вопрос:
Есть ли способ использовать scanf (без использования какой-либо другой функции ввода-вывода), чтобы проверить, существует ли пользовательский ввод только одного целого числа, за которым ничего не следует?
Например:
int g;
while(scanf("%d", amp;g)!=1){
printf("nincorrect input, try again");
}
Это отлично работает для ввода типа «/» или «-«, но когда вы вводите «54.32», он будет считываться до «.», количество прочитанных scanf будет равно 1, а 54 будет сохранено в g . Есть ли способ проверить, состоит ли ввод исключительно из одного целого числа, за которым следует только символ новой строки?
Я хотел бы знать, существует ли решение без использования fgets или любой другой функции ввода-вывода?
Комментарии:
1. scanf предназначен для чтения форматированных входных данных. Это бесполезно для неформатированной записи.
2.
"%d%c"
и затем, если возвращаемое значение равно 2, а символ нет'n'
— существуют посторонние символы. (но вы действительно должны выполнять весь пользовательский ввод сfgets()
помощью и, при необходимости, преобразования сsscanf()
помощью)
Ответ №1:
для проверки только одного целого числа, за которым следует только символ новой строки
Используйте "%n"
для записи количества отсканированных символов, если это заходит так далеко.
int n = 0;
scanf("%d*1[n]%n", amp;g, amp;n);
if (n > 0) puts("input consists solely of a single integer followed by a newline");
Если результат не соответствует ожиданиям, необходим дополнительный код, чтобы справиться с ошибочным вводом.
Я рекомендую использовать fgets()
для решения более масштабной проблемы.
Комментарии:
1. Я вижу, что тест был отменен, просто потребовалось немного времени, чтобы понять, что ошибка сопоставления использовалась для предотвращения
"%n"
достижения. Мне все еще нужно"%d%*1[n]%n"
получить желаемое поведение.
Ответ №2:
Редактировать, потому что я неправильно понял вопрос: как насчет этого?
#include <stdio.h>
int main() {
int n;
char c;
scanf("%d", amp;n);
scanf(" %c", amp;c) ? printf("incorrect input, try againn") : printf("%dn", n);
return 0;
}
Комментарии:
1. OP действительно запрашивал «за которым не следует ничего, кроме символа новой строки». Этот ответ не определяет, успешно ли новая строка последовала за an
int
. Он соответствует ttitle .2. @chux-ReinstateMonica ОП запрашивает чтение
54
, когда пользователь вводит54.32
, и это значение с плавающей запятой или значение int, за которым следует точка, за которой следует другое значение int. В любом случае программа работает даже для целых чисел, за которыми следует только новая строка.3. @chux-ReinstateMonica Перечитывая вопрос, я, возможно, действительно ошибся. Прошу прощения.
4. Опубликованные цели OP немного противоречивы и не учитывают то, что должно оставаться непрочитанным, когда ввод не соответствует ожиданиям. IAC, OP понравился этот ответ
5. @chux-RestorateMonica ну, даже если ему понравился ответ, я отредактировал его, чтобы он соответствовал тому, что он задает в вопросе. Спасибо, что позволили мне заметить мою ошибку
Ответ №3:
Вы можете использовать оператор формата с подавлением присваивания, чтобы извлечь все (что угодно) после целого числа, и спецификатор формата чтения количества символов, чтобы увидеть, соответствует ли это чему-либо, без необходимости хранить его где-либо.
Смотрите вашу документацию.
Например,
int g, gchars, xchars;
scanf("%d%n%*s%n", amp;g, amp;gchars, amp;xchars);
if (xchars > gchars)
printf("%d extra characters discarded after integer %dn", xchars-gchars, g);
Комментарии:
1.
%*s
использует любую новую строку послеint
того, что может присутствовать. Его нельзя использовать, чтобы отличить, следует ли за новой строкойint
или что-то еще.