2016-11-11 54 views
0

我试图创建一个程序,将从10个赛车手的信息。该程序将获得并存储名字,姓氏,年龄,性别(m/f)和他们的比赛时间(hh:mm:ss)。为此,我计划为每个赛车手提供一个包含上述每个元素的结构数组。然后我遇到了问“请输入第一名赛车手的名字”的问题,因为“first”这个词需要更改为“second”,“third”等......循环将无法去做。于是我决定创建一个字符串数组,其中数组的第一个元素是单词“first”,依此类推。那么我可以通过循环访问places数组的每个元素来为每个赛车手打印正确的单词。字符串阵列,并打印这些元素

我对字符串和字符串数组不熟悉,我在网上搜索了一些帮助,并提出了下面的程序,它使用带指针的字符数组,我不太明白,必须是与弦乐有关。无论如何,当我运行程序时,我遇到了严重的问题,必须重新打开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); 


} 

现在,香港专业教育学院得到的东西去远一点,进出口运行到一个问题,现在我只要一输入完第一个整理程序退出了命令窗口和一个新的窗口出现的姓氏他说:

“异常在0x0FF6D0F1(ucrtbased.dll)在ConsoleApplication30.exe抛出:0000005:访问冲突写入位置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

'places [4] - place5;'是一个错字。编译器可能会就此提醒你。 – Evert

+0

它可能更标准的使用'char * place1 =“First”; char * place2 =“Second”;'等等 – Evert

+1

或者全部指定:'char * places [] = {“First”,“Second”,“Third”,...};'。这将更清晰。 – Evert

回答

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行places输入,而且还因为有远不如机会错过像

places[3] = place4; 
places[4] - place5; // <---- whoops 
places[5] = place6; 

虽然我们在这一个错字,

typedef struct DATASET 
{ // whatever 
}; 

没什么意义。它不会创建任何typedef名称,所以单词typedef是无用的。它相当于

struct DATASET 
{ // whatever 
}; 

正因为如此,该声明

DATASET data[MaxRacers]; 

无效在C.它是有效的在C++中,这可能意味着你使用的是C++编译器。如果您正在学习C,请确保您的源文件扩展名为.c

+0

我想我使用C++,我的源代码说source.cpp。我做了你建议的编辑,但它仍然不起作用。 – Dwhaley

+0

认为修复for循环语法会做到这一点,但它仍然疯狂地进入头文件中的一些调试器并冻结 – Dwhaley

+0

查看更新的答案。 –

1

在你这个问题的第二次迭代,你报告:

进出口运行到一个问题,现在我只要一输入完第一整理

相信的姓氏这个问题是由于你错误地宣布了data[]DATASETstruct,不是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()或编写自己的输入函数,例如我之前链接的输入函数。