我正在尝试创建一个程序,该程序将从10名参赛者那里获取信息。该程序将获取并存储其名字,姓氏,年龄,性别(m / f)和比赛时间(hh:mm:ss)。为此,我计划为每个赛车手提供一系列结构,其中包含上述每个元素。然后我遇到了问“请输入第一个赛车手的名字”的问题,因为“第一个”这个词需要改为“第二个”,“第三个”等等...一个循环将无法去做。所以我决定然后创建一个字符串数组,其中数组的第一个元素是“first”,依此类推。那么我可以通过访问places数组的每个元素,使用循环为每个racer打印正确的单词。
我对字符串和字符串数组不太熟悉,我在网上搜索了一些帮助并提出了以下程序,它使用带指针的字符数组,我不太明白,必须是某些东西与字符串有关。无论如何,当我运行程序时,我遇到了严重的问题,必须重新打开Visual Studio。希望有人能帮助我,帮助澄清一些关于这些字符串数组和指针重要性的谜团。谢谢!
#include <stdio.h>
#include <math.h>
typedef struct DATASET
{
char firstname[12], lastname[12], gender;
int age, hours, minutes, seconds;
};
#define MaxRacers 10
int main()
{
int i;
DATASET data[MaxRacers];
char *places[MaxRacers];
char place1[6] = "First";
char place2[7] = "Second";
char place3[6] = "Third";
char place4[7] = "Fourth";
char place5[6] = "Fifth";
char place6[6] = "Sixth";
char place7[8] = "Seventh";
char place8[7] = "Eighth";
char place9[6] = "Ninth";
char place10[6] = "Tenth";
places[0] = place1;
places[1] = place2;
places[2] = place3;
places[3] = place4;
places[4] - place5;
places[5] = place6;
places[6] = place7;
places[7] = place8;
places[8] = place9;
places[9] = place10;
printf("%s", places[1]); // TEST which works fine
for(i = 0, i < MaxRacers; i = i + 1;)
{
printf("Enter the name of the %s finisher\n", places[i]); // Problem
}
getchar();
return(0);
}
现在我的事情变得更进一步了,我现在遇到一个问题,一旦我完成输入第一个终结者的姓氏,程序退出命令窗口,然后出现一个新窗口:
“ConsoleApplication30.exe中0x0FF6D0F1(ucrtbased.dll)抛出异常:0xC0000005:访问冲突写入位置0xFFFFFFCC。
如果存在此异常的处理程序,则可以安全地继续该程序。“
#include <stdio.h>
#include <math.h>
struct DATASET
{
char firstname[12], lastname[12], gender;
int age, hours, minutes, seconds;
};
#define MaxRacers 10
int main()
{
int i;
DATASET data[MaxRacers];
char *places[] = { "First", "Second", "Third", "Fourth", "Fifth", "Sixth", "Seventh", "Eighth", "Ninth", "Tenth" };
for (i = 0; i < MaxRacers; i++)
{
printf("Enter the first name of the %s finisher:\n", places[i]);
scanf("%s", data[i].firstname);
printf("Enter the last name of the %s finisher:\n", places[i]);
scanf("%s", data[i].lastname);
printf("Enter the gender of the %s finisher: [m/f]: \n", places[i]);
scanf("%c", data[i].gender);
printf("Enter the age of the %s finisher:\n", places[i]);
scanf("%d", data[i].age);
printf("Enter the time of the %s finisher: [hh:mm:ss]\n", places[i]);
scanf("%d:%d:%d", data[i].hours, data[i].minutes, data[i].seconds);
printf("\n\n");
}
getchar();
return(0);
}
答案 0 :(得分:1)
for(i = 0, i < MaxRacers; i = i + 1;)
for
循环不起作用。试试这个:
for(i = 0; i < MaxRacers; i++)
// ^ ^
// | |
// semicolon here more idiomatic
此外,您应该使用惯用字符数组初始化:
char *places[MaxRacers] = { "First", "Second", ... };
不仅因为它比20行[{1}}更容易打字,而且因为错过错字的机会也少得多
places
虽然我们正在努力,
places[3] = place4;
places[4] - place5; // <---- whoops
places[5] = place6;
没什么意义。它不会创建任何typedef名称,因此单词typedef struct DATASET
{ // whatever
};
是无用的。它相当于
typedef
因此,这个声明
struct DATASET
{ // whatever
};
C中的 无效。它在C ++中有效,这可能意味着您正在使用C ++编译器。如果您正在学习C,请确保您的源文件扩展名为DATASET data[MaxRacers];
。
答案 1 :(得分:1)
在此问题的第二次迭代中,您报告:
我输入第一个终结者的姓氏后立即遇到问题
我认为此问题是由于您错误地声明了data[]
。 DATASET
是struct
,而不是typedef
,因此您需要:
struct DATASET data[MaxRacers];
但这揭示了一个新问题。您对scanf()
的来电有几个问题。首先,您未能提供地址以在多个实例中存储scanf()
的结果。要解决此问题,您需要更改为:
printf("Enter the gender of the %s finisher: [m/f]: \n", places[i]);
scanf("%c", &data[i].gender);
printf("Enter the age of the %s finisher:\n", places[i]);
scanf("%d", &data[i].age);
printf("Enter the time of the %s finisher: [hh:mm:ss]\n", places[i]);
scanf("%d:%d:%d", &data[i].hours, &data[i].minutes, &data[i].seconds);
但现在又出现了另一个问题。 (邪恶)函数scanf()
经常留下换行符和其他字符,污染输入流以用于下一个输入函数。 I personally usually write a function to handle user input in the form of strings,然后使用strtol()
转换结果,如果需要数字输入。
最简单的事情是,在将scanf()
与%c
说明符一起使用之前,只需编写一个函数来清除输入流:
void clear_stream(void)
{
int ch;
while ((ch = getchar()) != '\n' && ch != EOF)
continue; // remove unwanted characters
}
然后像这样修改输入代码:
printf("Enter the first name of the %s finisher:\n", places[i]);
scanf("%s", data[i].firstname);
printf("Enter the last name of the %s finisher:\n", places[i]);
scanf("%s", data[i].lastname);
printf("Enter the gender of the %s finisher: [m/f]: \n", places[i]);
clear_stream();
scanf("%c", &data[i].gender);
printf("Enter the age of the %s finisher:\n", places[i]);
scanf("%d", &data[i].age);
printf("Enter the time of the %s finisher: [hh:mm:ss]\n", places[i]);
scanf("%d:%d:%d", &data[i].hours, &data[i].minutes, &data[i].seconds);
printf("\n\n");
对于许多格式说明符,scanf()
会跳过前导空格,包括换行符。但是%c
说明符不是这样,这意味着如果你输入一个字符串,那么输入流中留下的换行符将被拾取而不是你想要的字符。
这些更改将使您的代码运行。但是你的输入方案很脆弱。它不会检查是否存在输入(scanf()
返回已读取的值的数量)并且它不验证值。您是否希望用户输入负年龄?我建议您至少重新考虑输入代码,以确保获得所需的输入。因为scanf()
容易出错,所以你应该考虑使用fgets()
或编写自己的输入函数,例如我之前链接的函数。