2016-08-09 32 views
0

私はCの初心者で、いくつかのプログラムを開発しようとしていますが、現在固執しています。問題は次のとおりです。以下のコードを実行すると、「名前を入力してください」という部分全体がスキップされ、「CPFを入力してください」という部分がすぐにスキップされます。ループ内にコードを追加するときに "for loop"全体をスキップする

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

void append(char subject[], const char insert[], int pos) { 
    char buf[100] = {}; 

    strncpy(buf, subject, pos); 
    int len = strlen(buf); 
    strcpy(buf+len, insert); 
    len += strlen(insert); 
    strcpy(buf+len, subject+pos); 

    strcpy(subject, buf); 
} 

int main() { 
    int i,j; 
    char name[21],filename[21],cpf[16]; 
    FILE *fp; 

    for (;strlen(name)<3;) { 
     name[0] = 0; 
     printf("Type your name (max characters: 20, no numbers allowed) \n"); 
     fflush (stdout); 
     fgets(name,21,stdin); 
     for(i=0; name[i]!='\0'; ++i) { 
      while (!((name[i]>='a'&&name[i]<='z') || (name[i]>='A'&&name[i]<='Z' || name[i]=='\0'))) { 
       for(j=i;name[j]!='\0';++j) { 
       name[j]=name[j+1]; 
       } 
      name[j]='\0'; 
      } 
     } 
     strtok(name, "\n"); 
     strcpy(filename,name); 
     strcat(filename, ".txt"); 
    } 
    fp = fopen(filename,"a"); 
    fprintf(fp,"Name:"); 
    fprintf(fp, name); 
    fflush(stdin); 

    for (;strlen(cpf)<11 || strlen(cpf)>11;) { 
     printf("Please enter your CPF, consisting of 11 numbers:\n"); 
     scanf("%s",&cpf); 
    } 
    append(cpf,".",3); 
    append(cpf,".",7); 
    append(cpf,"-",11); 
    fprintf(fp,"\nCPF: "); 
    fprintf(fp, cpf); 
    system("pause"); 
} 

ただし、私が下の部分にコメントすると、正常に動作します。あなたが見ることができるように

//  for(i=0; name[i]!='\0'; ++i) { 
//   while (!((name[i]>='a'&&name[i]<='z') || (name[i]>='A'&&name[i]<='Z' || name[i]=='\0'))) { 
//    for(j=i;name[j]!='\0';++j) { 
//    name[j]=name[j+1]; 
//    } 
//   name[j]='\0'; 
//   } 
//  } 

とき、私、私は、コードが名前からすべての余分な文字を削除し、名前だけのアルファベットの文字を作りたいが、それは「forループ」全体をスキップし、なぜ私はわかりませんこの特定の部分を入力してください。

提案がありますか?また、私はC言語に新しいので、あまりにも多くのコードが含まれている可能性があります、私に教えて自由に感じて、私は無関係な部分を削除します。

+6

'strlen(name)'の最初の呼び出しでは、 'name'は初期化されていないため、未定義の動作が発生します。 –

+0

輪郭部分がないと、なぜそれはしませんか?それから質問をします。 – Casz146

+1

あなたは新しいです。 .itはデバッガの使い方を学ぶのに最適な時間です...コードがどこにあるのかを見つけることができるように....また、いくつかの大きなコードを記述すると...それは非常に役に立ちます –

答えて

2

は、次の2行を見てみましょう:

char name[21],filename[21],cpf[16]; 
... 
for (;strlen(name)<3;) { 

まず、配列name(およびいくつかの他)を宣言しますが、それを初期化しないでください。その後、strlenの呼び出しで初期化されていないものを使用します。 nameの内容が不確定であるため、undefined behaviorになります。

使用する前に、配列またはその他のローカル変数を明示的に初期化する必要があります。

最も簡単な方法は、コードが異なる状況で異なる動作をする理由については

char name[21] = "", ...; 

のようなものをやっているので、未定義の動作です。定義されていない動作は、その定義によって、は未定義ですです。それはまさに何かが起きる可能性があることを意味します。のように一見がうまく動作します。また、クラッシュするか、nasal demonsを引き起こす可能性があります。

+0

これは多くのおかげで、はっきりとしたものでした!また、デバッガの使用も開始します。 – Casz146

1

nameはユニット化されていないので、strlen(name)は未定義の動作で、falseを返すようです。これを回避するには、do whileループにforループを変更してください。このループは、条件を確認する前に常に1回実行されます。これは次のようになります。

do { 
    //loop body that initializes name 
} while (strlen(name) < 3); 
関連する問題