избавиться от предупреждений sscanf()

Я читаю MAC-адреса (в стандартной шестнадцатеричной нотации, например 00:11:22:33:44:55) из стандартного ввода и преобразовываю их в 6-байтовую переменную hw_addr в виде десятичных знаков:

u8 hw_addr[6];

scanf("%2x:%2x:%2x:%2x:%2x:%2x", &hw_addr[0], &hw_addr[1], &hw_addr[2], &hw_addr[3], &hw_addr[4], &hw_addr[5]);

Единственная проблема в том, что я получаю 6 предупреждений scanf:

warning: format '%2x' expects type 'unsigned int *', but argument 3 has type 'u8 *'

.....

Есть ли способ избавиться от этих предупреждений, не тратя впустую целое число для каждого поля?


person vNik    schedule 17.02.2010    source источник
comment
зачем вам сохранять эти байты?   -  person    schedule 17.02.2010
comment
Используйте ответ unsigned hw_addr[6] или @Potatoswatter.   -  person chux - Reinstate Monica    schedule 28.01.2014


Ответы (4)



Просто используйте правильный тип

Итак, вы используете машину с миллиардами байтов оперативной памяти и хотите сохранить 6 из них?

Если вы храните массив из миллионов MAC-адресов, вы должны преобразовать их в упакованный формат после их чтения. Но никакого вреда не будет, если передать канонические целые числа в scanf().

Если на то пошло, если hw_addr[] является локальной переменной, то она вообще не использует пространство, поскольку она будет повторно использоваться для других локальных переменных после возврата из вашей функции.

Поскольку вы не можете оптимизировать все подряд, важно сосредоточить усилия по оптимизации на действительно важных вещах.

person DigitalRoss    schedule 17.02.2010
comment
Может быть, он не пытается ничего оптимизировать. Может быть, проще заставить функцию ввода-вывода возвращать то, что вы хотите, чем вводить локальный тип для приведения. - person Potatoswatter; 17.02.2010
comment
Я не единственный, кто прочитал это как заботу об экономии памяти. И он действительно сказал тратить int. Но независимо от намерения, у scanf() есть определенный интерфейс, который необходимо использовать, и от его использования не будет никакого вреда. - person DigitalRoss; 17.02.2010

Предупреждения указывают на серьезную проблему. Вы передаете указатели на байты без знака, но функция scanf будет записывать 32 бита в эти указатели. Для первых трех значений дополнительные 24 бита будут перезаписывать части массива hw_addr, но для последних трех значений вы перезаписываете некоторую другую переменную в стеке.

Чтобы избежать серьезного сбоя, по крайней мере, вам нужно увеличить адрес hw_addr.

u8 hw_addr[6+3];

По крайней мере, предотвратит уничтожение стека вашим кодом. Но на самом деле вы должны просто использовать значения правильного размера для scanf и впоследствии конвертировать из целых чисел обратно в байты без знака.

person John Knoeller    schedule 17.02.2010

вы читаете unsigned int в адрес char, это может быть не очень переносимым или безопасным. просто используйте массив int в качестве буфера для чтения, а затем скопируйте в массив байтов

person Anycorn    schedule 17.02.2010
comment
Машины с обратным порядком байтов @Matthew будут перезаписывать ранее отсканированные байты. Последний байт всегда будет переполняться, независимо от архитектуры. Int помогает, потому что тогда вы читаете n байтов в n байтов, а не в один байт - person Anycorn; 17.02.2010