2016-11-02 7 views
-3

https://www.codechef.com/problems/LCOLLISscanf文でのみ "%d"の代わりに "%1d"を使用するとどのような違いがありますか?

私はcodechefで上記の問題を解決していましたが、以下のコードを書きましたが、ランタイムエラー(SIGSEVG)が表示されました。

#include<stdio.h> 

int main(void) 
{ 
int t, n, m; 
scanf("%d", &t); 

while(t--) 
{ 
    scanf("%d %d", &n, &m); 

    int a[10][10], i, j, sum, ans; 

    for(i = 0; i < n; i++) 
    { 
     for(j = 0; j < m; j++) 
      scanf("%d", &a[i][j]); 
    } 

    ans = 0; 
    for(i = 0; i < m; i++) 
    { 
     sum = 0; 
     for(j = 0; j < n; j++) 
     { 
      if(a[j][i] == 1) 
       sum++; 
     } 


     if(sum > 1) 
      ans = ans + (sum * (sum - 1))/2; 
    } 

    printf("%d\n", ans); 
} 

return 0; 
} 

そして、ちょっと違うだけで私と全く同じ解決策の1つを見て受け入れました。コードは次のとおりです。

#include<stdio.h> 

int main(void) 
{ 
int t, n, m; 
scanf("%d", &t); 

while(t--) 
{ 
    scanf("%d %d", &n, &m); 

    int a[10][10], i, j, sum, ans; 

    for(i = 0; i < n; i++) 
    { 
     for(j = 0; j < m; j++) 
      scanf("%1d", &a[i][j]); // SEE RIGHT HERE ITS JUST A 1 BEFORE d 
    } 

    ans = 0; 
    for(i = 0; i < m; i++) 
    { 
     sum = 0; 
     for(j = 0; j < n; j++) 
     { 
      if(a[j][i] == 1) 
       sum++; 
     } 


     if(sum > 1) 
      ans = ans + (sum * (sum - 1))/2; 
    } 

    printf("%d\n", ans); 
} 

return 0; 
} 

ここで、1はすべての違いを作ります。 誰か助けてください。

+1

'%d 'は' int'を読み取り、 '%1d'は1桁を読み取っています –

+0

マニュアルページをお読みください。 googleのmanページも検索してください。 –

+0

これは間違った答えを与えていますが、 'n'や' m'が10より大きい場合を除き、なぜSIGSEGVを与えるのか分かりません。 –

答えて

1

幅指定子がない場合、scanf()は、1つ後に停止するのではなく、すべての数字を読み取ります。同じ行の次のscanf()は失敗し、定義されていない/ガベージ・データがマトリックスに残ります。何が続く整数111、むしろより3つのものとして扱われる

111 

:リンクされたページから1行目のだから

。これはもちろん、CodeChef側からは嫌です。 :)

scanf()を使用して1文字だけを読むのは超過しているので、もっと簡単なことができます。また

、あなたがscanf()は常にその戻り値をチェックし使用しない場合:それはI/Oだとそれがを失敗する可能性があります。

0

"%1d"の1は、の幅の制限です。スキャンされる空白スペースの後には、文字の(数字だけでなく)の最大数です。

"%d"は、スキャンする文字の最大数に制限されません。

int main() { 
    int i; 
    i = 42; sscanf(" 123", "%1d", &i); printf("%d\n", i); 
    i = 42; sscanf("123", "%1d", &i); printf("%d\n", i); 
    i = 42; sscanf("-123", "%1d", &i); printf("%d\n", i); 
    i = 42; sscanf("+123", "%1d", &i); printf("%d\n", i); 
    i = 42; sscanf(" -123", "%1d", &i); printf("%d\n", i); 
} 

出力

1 
1 
42 // Nothing saved into `i` 
42 //  " 
42 //  " 
0

それでは、私は、テキストファイルをスキャンするとしようと、そのファイルは、それらの間にスペースなしで二進数字の行列が含まれています。変換指定%dには、余分なフィールド(フィールド幅と精度フィールド)が定義されていません。スキャン中、%dは空白を探して整数の終わりを判断します。

しかし、この例では、スペースを持たないバイナリ行列を定義しているので、プログラムはガベージ値をスローします。 %1dのように、フィールド幅1を%dで定義することができます。これらは出力を出力する際に​​余分なスペースを追加しませんが、scanfは各整数が余分な空のフィールド(この場合はスペース)を持つ数字であることを認識します。 2桁の数字の間にスペースを入れていない場合でも、別の数字としてスキャンします。

たとえば、1001010を数字全体としてスキャンするのではなく、1001010を1と0の別の数字として別​​々にスキャンします。簡単なコード例を示します。

int main() 
    { 
     FILE *ptr; 

     int i,j,count_0=0,count_1=0; 
     int a[row][col]; 

     ptr=fopen("bin.txt","r"); 

     for(i=0;i<3;i++) 
     { 
      for(j=0;j<3;j++) 
      { 
       fscanf(ptr,"%1d",&a[i][j]); 

      } 
     } 

     for(i=0;i<3;i++) 
     { 
      for(j=0;j<3;j++) 
      { 
       printf("%1d",a[i][j]); 
      } 
      printf("\n"); 
     } 

    return 0; 
    } 
関連する問題