在循环内添加代码时,跳过整个“for循环”

时间:2016-08-09 18:40:59

标签: c

我是C的初学者并且一直在尝试开发一些程序,但我现在卡住了。问题如下:当我运行下面的代码时,它跳过整个“键入你的名字”部分并立即跳过所以“键入你的CPF”部分。

#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-loop”

有什么建议吗?此外,由于我是C的新手,我可能包含了太多代码,请随时告诉我,我将删除不相关的部分。

2 个答案:

答案 0 :(得分:2)

让我们看看这两行:

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

首先声明数组name(以及其他一些数组),但不要初始化它。然后在调用strlen时使用未初始化。这将导致undefined behavior,因为name的内容不确定

在使用之前,必须显式初始化数组或任何其他局部变量。

最简单的方法就是做

之类的事情
char name[21] = "", ...;

至于为什么代码在不同情况下的行为不同是因为未定义的行为。根据其定义,未定义的行为是 undefined 。它意味着几乎任何事情都可能发生,即使看似也能正常工作。它也可能崩溃或导致nasal demons

答案 1 :(得分:1)

您已将name单元化,因此strlen(name)是未定义的行为,似乎返回false。为避免这种情况,请尝试将for循环更改为do while循环,该循环在检查条件之前始终运行一次。这看起来像是:

do {
    //loop body that initializes name
} while (strlen(name) < 3);