Кэш arp предоставляется в качестве стандарта в наборе доступных данных SNMP. Вы можете использовать SNMP4J для записи тривиального агента для запроса этих данных.
, например. из командной строки SNMP toolset
snmpwalk $ {hostname} 1.3.6.1.2.1.4.22.1.2
(эта огромная строка с разделителями периодов является OID или идентификатор кеша ARP в терминах SNMP, который будет работать для всех реализаций SNMP)
scanf ()
читает именно то, что вы просили, оставив следующий \n
с конца этой строки в буфере, где fgets () [ ! d2] прочитает его. Либо сделайте что-нибудь, чтобы использовать новую строку, или (мое предпочтительное решение)
fgets ()
, а затем sscanf ()
из этой строки.
Следующее работает, если fgets ()
«пропущен» после использования scanf ()
После того, как вы сказали:
scanf ("% d", & amp; loops);
Скажите:
char мусор [100]; fgets (мусор, 100, STDIN);
Это сохранит все оставленные на входном буфере в переменной мусора.
Это эффективно очистит входной буфер и позволит вам использовать fgets ()
после.
EDIT: Недавно я узнал, что есть более легкое решение, чем выше. Если вы скажете getchar () после scanf (), это позволит вам использовать fgets () без проблем. getchar () получит следующий символ во входном буфере, который в этом случае будет «\n». После удаления '\n' из входного буфера fgets должен работать нормально.
Vayn,
Geekoaur ответил на ваш вопрос хорошо, я просто указываю еще одну «проблему» с вашим кодом.
Строка s1 [strlen (s1)] = '\ 0';
является no-op , если s1
уже полностью нулевое завершение до того, как оно выполняется.
Но если s1
NOT allready должным образом завершен нулем до того, как эта строка выполняется (и вам не повезло), это приведет к:
Это потому, что strlen
basicaly находит индекс существующего нуль-терминатора и возвращает его! Вот действительная, неоптимизированная реализация strlen:
int strlen (char * string) {int i = 0; while (string [i]! = '\ 0') {++ i; } return i; }
Итак ... Если вы ДЕЙСТВИТЕЛЬНО беспокоитесь о том, что строки НЕ были завершены нулями, вы сделали бы что-то вроде:
string [sizeof (string)] = '\ 0';
на локальных автоматических строках (где компилятор «знает» размер строки); [SIZE_OF_STRING]
для всех остальных строк, где SIZE_OF_STRING
(чаще всего) a #define
'd константа или переменная, которую вы поддерживаете специально для хранения текущего SIZE (не длина) динамически выделенной строки. И если вы ДЕЙСТВИТЕЛЬНО, ДЕЙСТВИТЕЛЬНО, ДЕЙСТВИТЕЛЬНО беспокоитесь о строках, (например, вы используете «грязные» методы libary (например, ATMI Tuxedo), вы также «очищаете» свои «строки возврата» перед передачей их методам подозрительной библиотеки с помощью:
memset (string, NULL, SIZE_OF_STRING);
DirtyFunction (/ * out * / string)
; string [SIZE_OF_STRING] = '\ 0' [! d15]
SIG11 - это полная привязка для поиска, потому что (если вы не «зацепите» их с помощью signal-processor и сказать иначе, они заставляют unix жестко завершать вашу программу, поэтому вы не можете ничего записывать (после факта), чтобы помочь выяснить, here-in-the-hell-do-that-come-from ... особенно учитывая, что во многих случаях строка кода, которая выбрасывает SIG11, не находится рядом с фактической причиной того, что строка теряет нулевой ограничитель.
Разве это имеет для вас смысл?
Cheers mate. Keith.
PS: ПРЕДУПРЕЖДЕНИЕ: strncpy
НЕ все пустил нуль ... вы, вероятно, имели в виду strlcpy
. Я узнал об этом трудным образом ... когда сработал биллинг на 60 миллионов долларов.
EDIT:
FYI: Вот «безопасная» (неоптимизированная) версия strlen который я назову strnlen
(я считаю, что это должно быть в stdlib . Sigh.).
// перенастраивает длину string (capped at size-1) int strnlen (char * string, int size) {int i = 0; while (i & lt; size & amp; & amp; string [i]! = '\ 0') {++ i; } return i; }
string [sizeof (string)] = '\ 0' [! D0]! Это будет писать запись \ 0
ПОСЛЕ выделенной памяти! sizeof (s1)
равен 101, а индекс s1 - от 0 до 100! Та же проблема возникает и с strnlen
. Если нет \ 0
, он вернет размер
, а не размер - 1
, как указано в комментарии!
– TrueY
18 February 2016 в 00:19
scanf
оставляет пробел во входном буфере, включая символы новой строки. Чтобы использовать fgets для чтения следующей строки, вам нужно вручную удалить оставшуюся часть текущей строки:
int c; do {c = getchar (); } while (c! = EOF & amp; c! = '\n');
, тогда как (c! = EOF & amp; c! = '\n');
не является хорошим. c
выходит за рамки.
– chux
23 February 2018 в 01:50
Я знаю, что это очень старый. Я новичок в c и хотел проверить свой метод, который использует getchar
:
#include & lt; stdio.h & gt; int main () {printf ("Введите свое имя \n"); char string [10]; scanf ("% s", строка); printf ("Hello% s \n", строка); // GetChar (); # un комментируя эту строку, fgets отлично работает !! printf («Пожалуйста, введите свое имя снова \n"); fgets (строка, 10, stdin); printf («Hello again% s», строка); GetChar (); }
«Michele \n»
(пробел после имени) и посмотреть, работает ли код «un commenting this line».
– chux
23 February 2018 в 01:53
просто поместите scanf ("% d \n", & amp; loops);
вместо scanf ("% d", & amp; loops);
Я решил вашу проблему. Теперь ваша программа работает нормально. Если у вас есть сомнения, вы можете спросить меня.
# include & lt; stdio.h & gt; #include & lt; string.h & gt; int main () {int i, age; char phone [10]; char name [100]; printf ("ENTER YOUR NAME:"); fgets (имя, 100, stdin); printf ("ВВОД ВАШЕГО ВОЗРАСТА:"); зсапЕ ( "% d", & амп; возраст); printf ("ВВОД ТЕЛЕФОННОГО НОМЕРА:"); scanf (""); fgets (телефон, 10, STDIN); printf ("\nСтадийная деталь \n"); printf ("Имя:"); fputs (name, stdout); printf («Возраст:% d \n», возраст); printf («Номер телефона:»); ставит (телефон); Е ( "---- \n"); return 0; }
scanf ()
, как я могу использовать новую строку? Благодарю. – Vayn 7 May 2011 в 00:59% * [^ \n]% * c
, чтобы пропустить любые символы в новой строке, а затем сама новая строка. – geekosaur 7 May 2011 в 01:07% * [^ \n]% * c
в конце формата на самом деле не будет работать, если после предыдущего чтения и перед новой строкой нет символов, поскольку то% * [^ \n]
не будет соответствовать, так что% * c
будет пропущен, а новая строка останется на входе. Вам нужно сделать% * c
в отдельном вызове scanf, чтобы он работал. – Chris Dodd 16 May 2016 в 01:59