2010-02-14 2 views
0
char* ReadNumericFormat = "%i"; 
int Read(void) 
{ 
    int Storage; 
    __asm 
    { 
     LEA EAX, [Storage] 
     PUSH EAX 
     PUSH DWORD PTR [ReadNumericFormat] 
     CALL DWORD PTR [scanf] 
     ADD ESP, 8 
     MOV EAX, DWORD PTR [Storage] 
    }  
} 

, когда пользователь вводит «023919», процедура возвращается 19.
Это функция или темнота - это стандарт?Почему результаты scanf отличаются от пользовательского ввода?

+1

Вы используете встроенный ассемблер для замены одной строки кода на C? Либо это упражнение для изучения встроенного ассемблера, либо вы действительно хотите узнать что-то об оптимизации. :-) –

+1

@Paul Tomblin: Я пытаюсь уменьшить код-байты. – Behrooz

+1

в этом случае это вариант 2. –

ответ

8

На самом деле это потому, что вы ввели восьмеричное число.

В C цифры, начинающиеся с 0, будут интерпретироваться как восьмеричные (базовые 8) литералы. Таким образом, в вашем входе

023919 

scanf найти ведущий нуль без x следующего, поэтому предполагается, что это восьмеричное число. Затем он потребляет 2 и 3, до 9, который не является действительной восьмеричной цифрой и останавливается. Так scanf теперь

023 

который

2*8 + 3 = 19 

Так процедура возвращает 19.


Используйте формат %d вместо %i, чтобы предотвратить это.

+0

, так что это * забытая * функция. Потому что scanf должен вызывать ошибку, когда строка ввода неверна. – Behrooz

+0

Нет, это scanf, действующий так, как это было на протяжении десятилетий, и способ документирования работы. –

1

Это то же самое, если вы использовали scanf напрямую (без встроенной сборки). «023» - это восьмеричное представление 19, а scanf останавливается на «9» в «0239», потому что это не может быть восьмеричная цифра.

Смежные вопросы