2017-02-17 3 views
0

私は、データベースの2つのエントリの姓と名を変更するために2つの文字列を読み込む次のメソッドを持っています。名前は常に小文字に変換され、ハイフンが文字列の最初または最後の文字でない限り、文字またはハイフンで名前を取得する必要があります。エラーが発生した場合、ユーザーに再度プロンプトが表示されます。私のCコードのロジックエラー

/* 
Prompts for a student name, and checks if input is correct. 
Returns 0 on success, -1 onEOF. 
If the user inputs an invalid entry, the error is ignored and the user is simply asked again. 
*/ 
int get_name(char *first, char *last) 
{ 
char input[LINESIZE]; 
char buffer[LINESIZE]; 
char buffer2[LINESIZE]; 
int i; 

while (1) 
{ 
    printf("\n%s", "Enter the Student Name "); 
    if (!fgets(input, LINESIZE, stdin)) 
    { 
     clearerr(stdin); 
     return -1; 
    } 
    if (sscanf(input, "%s %s", buffer, buffer2) == 2) 
    { 
     if (strlen(buffer) < 20 && strlen(buffer2) < 20 && strlen(buffer) >= 2 && strlen(buffer2) >= 2) /*checks to see if the length is at least 2, but less than 20*/ 
     { 
      for (i = 0; i < 20; i++) /*checks every character on the string, converts it to lower and then checks if it's a letter or a hyphen, restarts if not.*/ 
      { 
       if (isalpha(buffer[i])) 
       { 
        buffer[i] = tolower(buffer[i]); 
       } 
       if (isalpha(buffer2[i])) 
       { 
        buffer2[i] = tolower(buffer2[i]); 
       } 
       if (!isalpha(buffer[i]) && buffer[i] != '-') 
       { 
        break; 
       } 
       if (!isalpha(buffer2[i]) && buffer2[i] != '-') 
       { 
        break; 
       } 
      } 
      if (buffer[0] == '-' || buffer[(strlen(buffer) - 1)] == '-') 
      { 
       i = 0; 
      } 
      if (buffer2[0] == '-' || buffer2[(strlen(buffer2) - 1)] == '-') 
      { 
       i = 0; 
      } 
      if (i == 20) 
      { 
       sscanf(buffer, "%s", first); 
       sscanf(buffer2, "%s", last); 
       return 0; 
      } 
     } 
    } 
} 

}

私は(!isalpha(buffer[i]) && buffer[i] != '-')でラインにエラーを突き止めましたが、文が間違っている理由を私は理解することはできません。

たとえば、成功した入力は "john smith"または "homer er simpson"です。どちらの場合も、関数は0(成功)を返します。 入力が "Denny's White"、 "-alexa redfield"、 "albert"または "1234 5647"のようなものであれば、関数はちょうどやり直すべきです(ユーザーに再度プロンプトが表示される)。 現時点では、入力にかかわらず、関数はやり直します。

+1

は、例えば、入力、意図された出力、および実際の出力を表示してください。 –

+0

コメントがなければ、このコードのどの部分が意図されているかを知ることは本当に難しいです。たとえば、 'i'が20に達したのをなぜテストしていますか?何をしていると思いますか?そして、最後の二つの 'scanf'呼び出しはどうなると思いますか?二つの 'break'ステートメントの意図した目的は何ですか? –

+0

私の悪い、私はコメントを追加するために投稿を編集します。文字列中の各文字が文字かハイフンでないかどうかをforループが調べることを意図していたため、私はi == 20かどうかを調べています。 forループが正常に実行されると、i = 20で停止し、入力に問題はなく、0が返されます(これはメソッドが成功したことを意味します)。 sscanfは、最初に=をバッファに、最後をbuffer2にします。 – Snow

答えて

1

あなたのプログラムでメインロジックエラーは、同時に 2つの配列上の反復の固定数(20)とのforループを実行しているという事実です。姓と名の配列には2つの別々のループを実行する必要があります。また、これらの2つのループは各アレイのstrlenにのみ実行する必要があります。

for (i = 0; i < strlen(buffer); i++) 
{ 
    /* your existing stuff for the "buffer" */ 
} 

for (i = 0; i < strlen(buffer1); i++) 
{ 
    /* your existing stuff for the "buffer1" */ 
} 
+0

@WeatherVane、入力いただきありがとうございます。 "@ snow"、これもお読みください。 – VHS

+0

ありがとうございました!私のプログラムは現在意図したとおりに動作しています。 2番目のforループのiをjに変更しました。最後に両方のループが成功したことを確認する必要があるためです。 また、Weather Vaneの返信で、その意味がわからないのですか? – Snow

+0

@WeatherVane私は参照してください。これは 'buffer [strlen(buffer)] = '/ 0''というだけで簡単でしょうか、それとももっと複雑なものでしょうか? – Snow

0

警告: VHSが主な問題を持って次のサンプルを参照してください。しかし、これはコード内の構造上の問題を改善することができる点も指摘しています。ほとんどすべてのコードが各配列に対して複製されます。

アレイを操作する関数を作成すると、[おそらく]問題が分かりやすくなります。私はこの[ご容赦ください無償スタイルのクリーンアップ]を追加するようにコードを作り直しました

#include <stdio.h> 
#include <string.h> 
#include <ctype.h> 

#define LINESIZE 80 

int 
bufdo(char *buf) 
{ 
    int len; 
    int idx; 
    int chr; 
    int ret; 

    len = strlen(buf); 

    do { 
     // assume non-conforming 
     ret = -1; 

     // length too great 
     if (len >= 20) 
      break; 

     // length too small 
     if (len < 2) 
      break; 

     // begins with hyphen 
     if (buf[0] == '-') 
      break; 

     // ends with hyphen 
     if (buf[len - 1] == '-') 
      break; 

     // assume it will be okay 
     ret = len; 

     // convert to lowercase and check for bad chars 
     for (idx = 0; idx < len; ++idx) { 
      chr = buf[idx]; 

      if (isalpha(chr)) { 
       chr = tolower(chr); 
       buf[idx] = chr; 
       continue; 
      } 

      // non-hyphen char in name 
      if (chr != '-') { 
       ret = -1; 
       break; 
      } 
     } 
    } while (0); 

    return ret; 
} 

int 
get_name(char *first, char *last) 
{ 

    char input[LINESIZE]; 
    char buffer[LINESIZE]; 
    char buffer2[LINESIZE]; 
    int len1; 
    int len2; 
    int ret; 

    ret = -1; 

    while (1) { 
     printf("\n%s", "Enter the Student Name "); 
     fflush(stdout); 

     if (!fgets(input, LINESIZE, stdin)) { 
      clearerr(stdin); 
      break; 
     } 

     if (sscanf(input, "%s %s", buffer, buffer2) != 2) 
      continue; 

     len1 = bufdo(buffer); 
     len2 = bufdo(buffer2); 

     if ((len1 > 0) && (len2 > 0)) { 
      strcpy(first,buffer); 
      strcpy(last,buffer2); 
      ret = 0; 
      break; 
     } 
    } 

    return ret; 
} 
+0

ありがとう!これは間違いなく良い方法です。 – Snow

+0

あなたは大歓迎です!私は機能を細かく構築しています。もともと、私は 'getlen'と呼んでいました。ちょうど' strlen'と長さの範囲チェックでした。私は他のステップのための他の機能を作成しようとしていましたが、他のステップ/ステップを1つずつ追加して、機能にうまく収まると認識しました。したがって、結局、単一の機能で十分でした。経験則として、「スケール」(つまり、私のコード_scale_は十分ですか?)を検討することです。もう少し経験があれば、これらのデザインの選択肢は見やすくなり、[ほぼ]公理的になります。ハッピープログラミング! –

関連する問題