我是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的新手,我可能包含了太多代码,请随时告诉我,我将删除不相关的部分。
答案 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);