2016-03-23 1 views
0

私が書いたコードは、charポインタリストのa、c、t、およびgの数を数えることになっています。次に、入力されたcharがa、c、t、またはgでない場合、無効な文字をcharリストinvalidBaseに追加することになっています。代わりに、データagtcpoopを入力すると無効なベースが表示されますが、文字列が表示されない場合は、その文字は表示されません。助けてください!ここでは、コードは次のとおりネストされたif-elseステートメントが私に問題をもたらしています

void countBase(char *p) 
{ 
    int aCount = 0, cCount = 0, tCount = 0, gCount = 0; 
    char invalidBase[100]; 
    int i, j=0; 
    while(*p != '\0') 
{ 
    if(*p == 'A' || *p == 'a') 
    { 
    aCount++; 
    } 
    else if(*p == 'C' || *p == 'c') 
    { 
    cCount++; 
    } 
    else if(*p == 'T' || *p == 't') 
    { 
    tCount++; 
    } 
    else if(*p == 'G' || *p == 'g') 
    { 
    gCount++; 
    } 
    else 
    { 
    invalidBase[j] = *p; 
    } 
    j++; 
    p++; 
} 

for(i = 0; invalidBase[i] != '\0'; i++) 
{ 
    printf("Invalid Base: %c\n", invalidBase[i]); 
} 

printf(" A: %i\n C: %i\n T: %i\n G: %i\n", aCount, cCount, tCount, gCount); 
} 
+0

私の推測では、今、それについての詳細を考えた後、私は他の文で間接参照invalidBaseに必要があるということですか?ポインタを使って?そのようなelse文で* invalidBase = * p; j ++の代わりにinvalidBaseをインクリメントします。これは近いですか? **私はMIKECATS REPLYを実行した後にこの方法が間違っていると思っています!** – Cole

+0

いいえ、 'invalidBase'は配列なのでインクリメントすることはできませんし、ivalは自動的に変換されます。 'sizeof'オペランドまたは単項'& '演算子以外の式 – MikeCAT

+0

これらの多くの 'if-else'ステートメントの代わりに' switch'ステートメントを使いたいかもしれません。 – MikeCAT

答えて

3

前年比は不定である自動記憶域期間を有する初期化されていない変数の値を用いて未定義の動作を呼び出します。

を向上させるために:

  • インクリメントデータをinvalidBaseに格納されている場合にのみ、カウンタj
  • jを使用して印刷する長さを決定します。

の改善コード:あなたはこれらの多くのif-else文の代わりにswitchステートメントを使用することができます

void countBase(char *p) 
{ 
    int aCount = 0, cCount = 0, tCount = 0, gCount = 0; 
    char invalidBase[100]; 
    int i, j=0; 
    while(*p != '\0') 
    { 
     if(*p == 'A' || *p == 'a') 
     { 
     aCount++; 
     } 
     else if(*p == 'C' || *p == 'c') 
     { 
     cCount++; 
     } 
     else if(*p == 'T' || *p == 't') 
     { 
     tCount++; 
     } 
     else if(*p == 'G' || *p == 'g') 
     { 
     gCount++; 
     } 
     else 
     { 
     if(j < (int)(sizeof(invalidBase)/sizeof(*invalidBase))) /* avoid buffer overrun */ 
     { 
      invalidBase[j] = *p; 
      j++; 
     } 
     } 
     p++; 
    } 

    for(i = 0; i < j; i++) 
    { 
     printf("Invalid Base: %c\n", invalidBase[i]); 
    } 

    printf(" A: %i\n C: %i\n T: %i\n G: %i\n", aCount, cCount, tCount, gCount); 
} 

注意。

void countBase(char *p) 
{ 
    int aCount = 0, cCount = 0, tCount = 0, gCount = 0; 
    char invalidBase[100]; 
    int i, j=0; 
    while(*p != '\0') 
    { 
     switch(*p) 
     { 
     case 'A': 
     case 'a': 
     aCount++; 
     break; 
     case 'C': 
     case 'c': 
     cCount++; 
     break; 
     case 'T': 
     case 't': 
     tCount++; 
     break; 
     case 'G': 
     case 'g': 
     gCount++; 
     break; 
     default: 
     if(j < (int)(sizeof(invalidBase)/sizeof(*invalidBase))) /* avoid buffer overrun */ 
     { 
      invalidBase[j] = *p; 
      j++; 
     } 
     break; 
     } 
     p++; 
    } 

    for(i = 0; i < j; i++) 
    { 
     printf("Invalid Base: %c\n", invalidBase[i]); 
    } 

    printf(" A: %i\n C: %i\n T: %i\n G: %i\n", aCount, cCount, tCount, gCount); 
} 
+0

私はあなたを愛している神<3。そのような愚かな誤り。ありがとうございました....私はこれを永遠に見ました。私が何か間違っていると思っている入れ子のifループについては、これほど多くの研究をしていました。ありがとうございます<3 – Cole

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

void countBase(char *p) { 
    int aCount = 0, cCount = 0, tCount = 0, gCount = 0; 
    char invalidBase[100]; 
    int i, j=0; 
    while(*p != '\0') { 
     if(tolower(*p) == 'a') { 
      aCount++; 
     } 
     else if(tolower(*p) == 'c') { 
      cCount++; 
     } 
     else if(tolower(*p) == 't') { 
      tCount++; 
     } 
     else if(tolower(*p) == 'g') { 
      gCount++; 
     } 
     else { 
      // This is the correct place to increment j. 
      invalidBase[j++] = *p; 
     } 

     // The following line is wrong. You can only increment j if an invalid 
     // base was found and inserted on the array. 
     // j++; 
     p++; 
    } 

    // Your code lacked the "end of string" delimitation. 
    invalidBase[j] = '\0'; 

    for(i = 0; invalidBase[i] != '\0'; i++) { 
     printf("Invalid Base: %c\n", invalidBase[i]); 
    } 

    printf(" A: %i\n C: %i\n T: %i\n G: %i\n", aCount, cCount, tCount, gCount); 
} 

int main(){ 
    printf("Testing '%s'\n", "agtcpoop"); 
    countBase("agtcpoop"); 
    puts("***********************************"); 
    printf("Testing '%s'\n", "a"); 
    countBase("a"); 
    puts("***********************************"); 
    printf("Testing '%s'\n", ""); 
    countBase(""); 
    puts("***********************************"); 
    printf("Testing '%s'\n", "p"); 
    countBase("p"); 
    return 0; 
} 
+0

ああ!私はこれが好き!どうもありがとうございました!とても清潔です。また、\ 0が自動的に追加されたと思いますか?私はポインタにそれを加えたことはありません! – Cole

+0

この 'tolower()'の使用は、範囲外の値を渡すために*未定義の動作*を呼び出すかもしれません。渡す前に '* p'を' unsigned char'にキャストするのは良いことです。 – MikeCAT

関連する問題