2016-08-27 2 views
4

mainfのscanf()は、デバッグprintf()のように、ゼロ以外の数値からの入力番号の1つを0に変換します。 whileループで。私はいくつかのコンパイラでそれをテストしましたが、同じ結果が得られるだけです。なぜこのようなものなのか教えてください。ありがとうございました。ゼロ以外の入力をゼロにする

#include <stdio.h> 

unsigned srl (unsigned x, int k) 
{ 
    /* perform shift arithmetically */ 
    printf("x = %u, (int) x= %d\n", x, (int) x); 
    unsigned xsra = (int) x >> k; 
    printf("\nxsra before was: %u\n", xsra); 
    unsigned test = 0xffffffff; 
    test <<= ((sizeof (int) << 3) - k); // get e.g., 0xfff00... 
    printf("test after shift is: %x, xsra & test = %x\n", test, xsra & test); 
    if (xsra & test == 0) // if xsrl is positve 
     return xsra; 
    else 
     xsra ^= test; // turn 1s into 0s 

    return xsra; 
} 

int sra (int x, int k) 
{ 
    /* perform shift logically */ 
    int xsrl = (unsigned) x >> k; 
    unsigned test = 0xffffffff; 
    test << ((sizeof (int) << 3) - k + 1); // get e.g., 0xffff00... 
    if (xsrl & test == 0) // if xsrl is positve 
     return xsrl; 
    else 
          xsrl |= test; 

     return xsrl; 
} 

int main(void) 
{ 
    int a; 
    unsigned b; 
    unsigned short n; 

    puts("Enter an integer and a positive integer (q or negative second number to quit): "); 
    while(scanf("%d%u", &a, &b) == 2 && b > 0) 
    { 
     printf("Enter the number of shifts (between 0 and %d): ", (sizeof (int) << 3) - 1); 
     scanf("%d", &n); 
     if (n < 0 || n >= ((sizeof (int)) << 3)) 
     { 
      printf("The number of shifts should be between 0 and %d.\n", ((sizeof (int)) << 3) - 1); 
      break; 
     } 
     printf("\nBefore shifting, int a = %d, unsigned b = %u\n", a, b); 
     a = sra(a, n); 
     b = srl(b, n); 
     printf("\nAfter shifting, int a = %d, unsigned b = %u\n", a, b); 
     puts("\nEnter an integer and a positive integer (q or negative second number to quit): "); 
    } 
    puts("Done!"); 

    return 0; 
} 
+2

'unsgined short'の指定子は'%hu'であり、 '%u'ではありません。 – ameyCU

+0

あなたが私に何が0になったのかを教えてもらえればもっと簡単になりましたので、私は自分自身で全体をコンパイルする必要はありませんでした...(実際は、再ロードしてameyを見てコメント)また、OP、 'n'は' unsigned'のように負になることはありません。 – RastaJedi

+1

彼は実際には間違っていますが、 'n 'には'%d'を使用していますが、 '%u'では使用していません。 – RastaJedi

答えて

4

問題はnが正常int未満のサイズを有するunsigned short、ということです。 scanf("%d", &n);を呼び出すと、nに値が読み込まれ、の直後のメモリ位置がbの場合、既存のbの値が上書きされる可能性があります。

あなたがしなければならないことに問題のある行を変更することです:

scanf("%hu", &n); 

hhereから、unsigned short intための修飾子です。

+2

これは '-Wall'と' -Wextra'で常にコンパイルするべき理由のもう一つの例です。 – RastaJedi

+0

ありがとう、lyang。あなたの答えはとても役に立ちます。それは間違った入力形式指定子のためにオーバーフローが発生しているのです。 –

+0

ありがとう、RastaJedi。私は、-Wallと-Wextraオプションはデフォルトであると仮定していましたが、実際にはすべてのコンパイラでデフォルトではありません –

関連する問題