2016-04-01 13 views
1

私はGoogle Code Jamの練習問題(hereを読むことができます)でグループと作業していました。次のように私たちのコードは次のとおりです。C文字列での予期しない入力

#include <stdio.h> 
#include <stdlib.h> 
#include <stdbool.h> 

main(){ 
    int c; 
    int n = 0; 
    int l = 0; 
    int d = 0; 
    int caseCount = 0; 
    int i = 0; 
    int j = 0; 
    //A boolean value used in determining parenthesees. 
    bool letBool = false; 
    //A boolean value used in determining something; 
    bool wordBool = false; 
    //Temporary space for test characters 
    char test[1000]; 
    //Gets word length 
    while((c=getchar())!=' ' && c!= '\n'){ 
    l = (l * 10) + c - '0'; 
    //printf("%d\n", l); 
    } 
    //Gets number of valid words. 
    while((c=getchar())!=' ' && c!= '\n'){ 
    d = (d * 10) + c - '0'; 
    //printf("%d\n", d); 
    } 
    //Gets number of test cases. 
    while((c=getchar())!= '\n'){ 
    n = (n * 10) + c - '0'; 
    //printf("%d\n", n); 
    } 
    //Array of all valid words. 
    char dict[d][l]; 
    c=getchar(); 
    //While we still have words to read in. 
    while(i < d){ 
    //If not new line 
    if(c!='\n'){ 
     //Then read character 
     dict[i][j] = c; 
    } 
    else{ 
     i++; 
     j=0; 
    } 
    c=getchar(); 
    j++; 
    } 
    i = 0; 
    j = 0; 
    while(i < n){ 
    j = 0; 
    while((c=getchar())!='\n' && c!=EOF){ 
     putchar(c); 
     test[j] = c; 
     j++; 
    } 
    putchar('\n'); 
    test[j+1] = '\0'; 
    printf("%s\n", test); 
    int word = 0; 
    //Going through valid words 
    while(word < d){ 
     wordBool=true; 
     j = 0; 
     int letter = 0; 
     //Going through valid letters 
     while(letter < l){ 
     letBool=false; 
     if(test[j] == '('){ 
      while(test[j++]!=')'){ 
      if(dict[word][letter]==test[j]){ 
       letBool=true; 
       //printf("%s%d%s%d\n" "letBool is true at word: ", word, "letter: ", letter); 
      } 
      } 
     } 
     else{ 
      if(test[j]==dict[word][letter]){ 
      letBool=true; 
      //printf("%s%d%s%d\n" "letBool is true at word: ", word, "letter: ", letter); 
      } 
     } 
     j++; 
     letter++; 
     if(!letBool){ 
      wordBool=false; 
      //printf("%s%d%s%d\n" "wordBool is false at word: ", word, "letter: ", letter); 
     } 
     } 
     if(wordBool){ 
     caseCount++; 
     } 
     word++; 
    } 
    printf("%s%d%s%d\n", "Case #", i+1, ": ", caseCount); 
    i++; 
    j=0; 
    caseCount=0; 
    } 
} 

問題が出力され、正しくうちのputcharで「受け取った外国人のコード」の部分のための入力を読み込むように見えるが、それはテストケースに入力されたとき、それが破損します。我々はそれをこの入力与えるとき

while((c=getchar())!='\n' && c!=EOF){ 
     putchar(c); 
     test[j] = c; 
     j++; 
    } 
    putchar('\n'); 
    test[j+1] = '\0'; 
    printf("%s\n", test); 

:ここで私が話しています一部です

3 5 4 
abc 
bca 
dac 
dbc 
cba 
(ab)(bc)(ca) 
abc 
(abc)(abc)(abc) 
(zyx)bc 

は、我々はそう

ab)(bc)(ca) 
ab)(bc)(ca) 
7 
Case #1: 0 
abc 
abc 
b 
Case #2: 1 
(abc)(abc)(abc) 
(abc)(abc)(abc) 
Case #3: 0 
(zyx)bc 
(zyx)bcb 
Case #4: 0 

(
Case #5: 0 

を取得し、我々はランダムがある理由を理解することはできません7やbのような文字が印刷されます。

+1

一つのバグはここにある: 'テスト[J +1] = '\ 0'; '' test [j] = '\ 0'; '' j 'は既に前の文字インデックスを超えてインクリメントされているためです。 –

+0

ありがとうございました! – MegaZeroX

+0

これはコンテストサイトです。あなたは自分で問題を解決することをお勧めします。あなたは答えを見つけても、いつも「チート」のサイトがあります。 –

答えて

0

変更この:これに

test[j+1] = '\0'; 

test[j] = '\0'; 

理由は、終了条件が満たされた前にすでに、whileループの最後で、jの値をインクリメントということです:

j = 0; 
while((c=getchar())!='\n' && c!=EOF){ 
    putchar(c); 
    test[j] = c; 
    j++; <------ 
} 
putchar('\n'); 
test[j] = '\0'; 

したがって、test[j + 1]では、実際にはセルをキップした。つまり、testは何も初期化されていないため、スキップされたセルには迷惑メールが含まれているため、未定義の動作が発生しています。結果として、私たちはその細胞が何を含んでいるのか分からず、ジャンクを含んでいます。修正されたコードと

出力:また

[email protected]:~$ gcc -Wall px.c 
[email protected]:~$ ./a.out 
3 5 4 
abc 
bca 
dac 
dbc 
cba 
(ab)(bc)(ca) 
abc 
(abc)(abc)(abc) 
(zyx)bcab)(bc)(ca) 
ab)(bc)(ca) 
Case #1: 0 
abc 
abc 
Case #2: 1 
(abc)(abc)(abc) 
(abc)(abc)(abc) 
Case #3: 0 

(zyx)bc 
(zyx)bc 
Case #4: 0 

、使用:より多くの場合

int main(void) { 
    ... 
    return 0; 
} 

は、これを読んで:What should main() return in C and C++?

+1

ありがとう!私は今、Cを学んでいるので、主な機能がこれらの基準を持つことが期待されていることは分かりませんでした。申し訳ありませんが質問がうまく尋ねられなかった場合、上級生として数分前に私に言ったように!私が本当に必要なのは、問題の残りの部分が間違いなく、私たちが正しい数の症例を得ていない理由を理解する能力の中にあるからです! – MegaZeroX

+0

@MegaZeroXを学んだことがあります。 :)私の更新された答えを確認してください(ちょうど今でした)!わかった、うまくいくといいね! – gsamaras

関連する問題