C 循环执行不正确
我有一个函数readin()读取许多人的姓名及其对应的电话号码 编号并返回已输入的名称数。字符“#”用于表示用户输入结束C 循环执行不正确,c,do-while,C,Do While,我有一个函数readin()读取许多人的姓名及其对应的电话号码 编号并返回已输入的名称数。字符“#”用于表示用户输入结束 int readin(Employee *emp) { int i=0,j; do { // loop statements to be executed no matter what printf("Enter name:\n"); scanf("%s",emp->name); // stores name inside
int readin(Employee *emp)
{
int i=0,j;
do { // loop statements to be executed no matter what
printf("Enter name:\n");
scanf("%s",emp->name); // stores name inside structure array
j = (strcmp(emp->name,"#") != 0); // returns 1 if name not equals to #
} while(j);{ // while name is not equals to # , execute code below and loop back 'do'
printf("Enter tel:\n");
scanf("%s",emp->telno);
emp++;
i++;
}
return i;
}
预期结果应为:
Enter name:
John
Enter tel:
12345678
Enter name:
#
取得的结果:
Enter name:
John
Enter name:
#
Enter tel:
当j=1时,while循环不会运行,但它会循环回do部分,而不是完全退出循环。
当j=0时,while循环中的代码出于某种原因被执行。请给出建议。你知道这就是你工作时的样子
do{
state1;
}
while(statement);
rest of code;
如果这句话是真的,
它将转到状态部分并再次执行,当语句出错时,它将转到代码的其余部分
在你的情况下,当字符串!='#'您将始终进入do while()循环,当语句错误或j==0
时,您将退出do while循环
我建议:
int readin(Employee* emp)
{
int i = 0, j =0;
while (1)
{
printf("Enter name:\n");
scanf("%s", &emp->name);
if((strcmp(emp->name, "#") == 0))
break;
printf("Enter tel:\n");
scanf("%s", &emp->telno);
emp++;
i++;
}
return i;
}
使用
scanf
进行面向行的输入是错误的选择。建议使用fgets()
或POSIXgetline()
读取用户输入行
为什么使用fgets()?
简而言之,它更健壮,它处理内部空白,允许您输入“first-last”
名称或“(409)555-1212”
,就像telno(scanf()
和“%s”
不能)一样,您唯一的责任是验证返回,然后从输入中修剪尾部的'\n'
。验证返回以处理手动生成的EOF
,用户在Linux上按Ctrl+d或在windows上按Ctrl+z取消输入。(正如您必须为scanf()
)做的一样,作为一项好处,您不需要输入'
来结束输入,因为fgets()
读取'\n'
,当单独按下enter键时,用户只需在一个空名称
行上按enter键即可退出
例如,您可以读取并验证输入的姓名和电话号码字符串是否简单,如下所示:
#define MAXTEL 32 /* if you need a constant, #define one (or more) */
#define MAXNM 64
#define MAXEMP 128
typedef struct {
char name[MAXNM],
telno[MAXTEL];
} employee;
int readin (employee *emp)
{
int n;
for (n = 0; n < MAXEMP; n++) { /* loop continually - protect array bounds */
fputs ("\nEnter name: ", stdout); /* prompt */
/* read/validate, check for Enter alone to exit */
if (!fgets (emp[n].name, MAXNM, stdin) || *emp[n].name == '\n')
break;
emp[n].name[strcspn(emp[n].name, "\n")] = 0; /* trim trailing \n */
fputs ("Enter tel : ", stdout); /* prompt */
if (!fgets (emp[n].telno, MAXTEL, stdin)) /* read/validate */
break;
emp[n].telno[strcspn(emp[n].telno, "\n")] = 0; /* trim trailing \n */
}
return n;
}
您仍然需要输入一个“#”
来终止输入,这应该是不必要的
你愿意用哪一种
示例
使用以下任一函数:
int main (void) {
employee e[MAXEMP] = {{ .name = "" }};
int n = readin (e);
for (int i = 0; i < n; i++)
printf ("\nemployee:\n name : %s\n telno : %s\n",
e[i].name, e[i].telno);
}
示例使用/输出-scanf()
下面显示了完整的示例,只需将-dusescan
添加到编译字符串中(或VS的/D USESCANF
)即可使用scanf()
版本,默认情况下使用fgets()
。总的来说,没有理由使用scanf()
读取两个用户输入字符串。使用面向行的输入函数从用户处读取输入行,您会得到更好的服务:
#include <stdio.h>
#include <string.h>
#define MAXTEL 32 /* if you need a constant, #define one (or more) */
#define MAXNM 64
#define MAXEMP 128
typedef struct {
char name[MAXNM],
telno[MAXTEL];
} employee;
#ifndef USESCANF
int readin (employee *emp)
{
int n;
for (n = 0; n < MAXEMP; n++) { /* loop continually - protect array bounds */
fputs ("\nEnter name: ", stdout); /* prompt */
/* read/validate, check for Enter alone to exit */
if (!fgets (emp[n].name, MAXNM, stdin) || *emp[n].name == '\n')
break;
emp[n].name[strcspn(emp[n].name, "\n")] = 0; /* trim trailing \n */
fputs ("Enter tel : ", stdout); /* prompt */
if (!fgets (emp[n].telno, MAXTEL, stdin)) /* read/validate */
break;
emp[n].telno[strcspn(emp[n].telno, "\n")] = 0; /* trim trailing \n */
}
return n;
}
#else
int readin (employee *emp)
{
int n;
for (n = 0; n < MAXEMP; n++) { /* loop continually - protect array bounds */
int rtn; /* variable to save the return of scanf */
fputs ("\nEnter name: ", stdout); /* prompt */
rtn = scanf(" %63[^\n]", emp->name); /* read into tmp saving return */
if (rtn == EOF) { /* handle EOF - user presses Ctrl+d (Ctrl+z win) */
fputs ("(user canceled input)\n", stderr);
break;
}
else if (rtn == 1 && *emp->name == '#') /* good input and '#' -- bail */
break;
for (;;) { /* loop contianually until valid telno entered */
fputs ("Enter tel : ", stdout); /* prompt */
rtn = scanf(" %31[^\n]", emp->telno); /* read saving return */
if (rtn == EOF) { /* handle EOF - ditto */
fputs ("(user canceled input)\n", stderr);
break;
}
else if (rtn == 1) { /* good input */
/* further validate telno here */
break;
}
} /* empty trailing \n from stdin */
for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
emp++; /* advance pointer */
}
return n; /* return success */
}
#endif
int main (void) {
employee e[MAXEMP] = {{ .name = "" }};
int n = readin (e);
for (int i = 0; i < n; i++)
printf ("\nemployee:\n name : %s\n telno : %s\n",
e[i].name, e[i].telno);
}
#包括
#包括
#定义MAXTEL 32/*如果需要常数,请定义一个(或多个)*/
#定义maxm64
#定义MAXEMP 128
类型定义结构{
字符名[MAXNM],
telno[MAXTEL];
}员工;
#ifndef USESCANF
int readin(员工*emp)
{
int n;
对于(n=0;nname);/*读入tmp保存返回*/
如果(rtn==EOF){/*句柄EOF-用户按下Ctrl+d(Ctrl+z)*/
fputs(“(用户取消输入)\n”,stderr);
打破
}
如果(rtn==1&&*emp->name=='#')/*输入正确且'#'--bail*/
打破
for(;;){/*循环,直到输入有效的telno*/
fputs(“输入电话:,标准输出);/*提示*/
rtn=scanf(“%31[^\n]”,emp->telno);/*读取保存返回*/
if(rtn==EOF){/*句柄EOF-同上*/
fputs(“(用户取消输入)\n”,stderr);
打破
}
else如果(rtn==1){/*输入正确*/
/*在这里进一步验证telno*/
打破
}
}/*空尾随\n来自标准输入*/
对于(int c=getchar();c!='\n'&&c!=EOF;c=getchar()){}
emp++;/*高级指针*/
}
返回n;/*返回成功*/
}
#恩迪夫
内部主(空){
雇员e[MAXEMP]={{.name=”“};
int n=读入(e);
对于(int i=0;i
仔细检查一下,如果您还有其他问题,请告诉我。在
}while(j)上的缩进或行分割(或不存在缩进或行分割);{
令人担忧。do{…}while(j)
循环以分号结尾。{
是一个独立的复合语句,与do
-while
循环无关。do
-while
将重复输入员工姓名,直到您用
覆盖它(循环将结束,但之前的条目已丢失-名称为“#”
)。然后输入电话号码once@JonathanLeffler理解。似乎我对do循环有一个误解。我错过了emp++
,它将数组作为参数传递。因此,您可以得到多个em
$ ./bin/empnametelnoarray
Enter name: John Q. Public
Enter tel : 444-1212
Enter name: Sally P. Public
Enter tel : 444-1222
Enter name: Mary Jane
Enter tel : 444-1223
Enter name:
employee:
name : John Q. Public
telno : 444-1212
employee:
name : Sally P. Public
telno : 444-1222
employee:
name : Mary Jane
telno : 444-1223
$ ./bin/empnametelnoarray
Enter name: John Q. Public
Enter tel : 444-1212
Enter name: Sally P. Public
Enter tel : 444-1222
Enter name: Mary Jane
Enter tel : 444-1223
Enter name: #
employee:
name : John Q. Public
telno : 444-1212
employee:
name : Sally P. Public
telno : 444-1222
employee:
name : Mary Jane
telno : 444-1223
#include <stdio.h>
#include <string.h>
#define MAXTEL 32 /* if you need a constant, #define one (or more) */
#define MAXNM 64
#define MAXEMP 128
typedef struct {
char name[MAXNM],
telno[MAXTEL];
} employee;
#ifndef USESCANF
int readin (employee *emp)
{
int n;
for (n = 0; n < MAXEMP; n++) { /* loop continually - protect array bounds */
fputs ("\nEnter name: ", stdout); /* prompt */
/* read/validate, check for Enter alone to exit */
if (!fgets (emp[n].name, MAXNM, stdin) || *emp[n].name == '\n')
break;
emp[n].name[strcspn(emp[n].name, "\n")] = 0; /* trim trailing \n */
fputs ("Enter tel : ", stdout); /* prompt */
if (!fgets (emp[n].telno, MAXTEL, stdin)) /* read/validate */
break;
emp[n].telno[strcspn(emp[n].telno, "\n")] = 0; /* trim trailing \n */
}
return n;
}
#else
int readin (employee *emp)
{
int n;
for (n = 0; n < MAXEMP; n++) { /* loop continually - protect array bounds */
int rtn; /* variable to save the return of scanf */
fputs ("\nEnter name: ", stdout); /* prompt */
rtn = scanf(" %63[^\n]", emp->name); /* read into tmp saving return */
if (rtn == EOF) { /* handle EOF - user presses Ctrl+d (Ctrl+z win) */
fputs ("(user canceled input)\n", stderr);
break;
}
else if (rtn == 1 && *emp->name == '#') /* good input and '#' -- bail */
break;
for (;;) { /* loop contianually until valid telno entered */
fputs ("Enter tel : ", stdout); /* prompt */
rtn = scanf(" %31[^\n]", emp->telno); /* read saving return */
if (rtn == EOF) { /* handle EOF - ditto */
fputs ("(user canceled input)\n", stderr);
break;
}
else if (rtn == 1) { /* good input */
/* further validate telno here */
break;
}
} /* empty trailing \n from stdin */
for (int c = getchar(); c != '\n' && c != EOF; c = getchar()) {}
emp++; /* advance pointer */
}
return n; /* return success */
}
#endif
int main (void) {
employee e[MAXEMP] = {{ .name = "" }};
int n = readin (e);
for (int i = 0; i < n; i++)
printf ("\nemployee:\n name : %s\n telno : %s\n",
e[i].name, e[i].telno);
}