Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C初级读物5-任务14-6_C - Fatal编程技术网

C初级读物5-任务14-6

C初级读物5-任务14-6,c,C,文本文件保存有关垒球队的信息。每条线的数据排列如下: 4 Jessie Joybat 5 2 1 1 第一项是玩家的号码,方便地在0-18之间。第二项是玩家的名字,第三项是玩家的姓氏。每个名字都是一个单词。下一项是球员的正式击球时间,然后是击球次数、行走次数和跑动次数(打点)。该文件可能包含多个游戏的数据,因此同一玩家可能有多行数据,这些行之间可能有其他玩家的数据。编写一个程序,将数据存储到结构数组中。该结构应具有代表姓名、at击球数、击球数、步行和打点(击球时的跑动)以及击球平均数(稍后计算)

文本文件保存有关垒球队的信息。每条线的数据排列如下:

4 Jessie Joybat 5 2 1 1

第一项是玩家的号码,方便地在0-18之间。第二项是玩家的名字,第三项是玩家的姓氏。每个名字都是一个单词。下一项是球员的正式击球时间,然后是击球次数、行走次数和跑动次数(打点)。该文件可能包含多个游戏的数据,因此同一玩家可能有多行数据,这些行之间可能有其他玩家的数据。编写一个程序,将数据存储到结构数组中。该结构应具有代表姓名、at击球数、击球数、步行和打点(击球时的跑动)以及击球平均数(稍后计算)的成员。您可以使用玩家编号作为数组索引。程序应该读取到文件的末尾,并且应该保存每个玩家的累积总数

棒球统计的世界是一个复杂的世界。例如,基于错误的步行或到达基地不算作at bat,但可能产生RBI。但是这个程序所要做的就是读取和处理数据文件,如下所述,而不必担心数据的真实性

程序运行的最简单方法是将结构内容初始化为零,将文件数据读入临时变量,然后将它们添加到相应结构的内容中。程序读取完文件后,应计算每个球员的击球平均数,并将其存储在相应的结构成员中。击球平均数的计算方法是将球员的累计击球次数除以累计击球次数;它应该是浮点计算。然后,程序应该显示每个球员的累积数据,以及一行显示整个球队的综合统计数据


team.txt(我正在使用的文本文件):


由于我是C语言的初学者,要么我误解了最初要求的任务,要么它不公平地复杂(我相信前一种情况就是如此)。我太迷茫了,我想不出怎么用索引(球员编号)的标准填写每一条数据,跟踪他是否有多场比赛,计算并获取平均击球数,然后打印出来

到目前为止,我得到的是:

#define LGT 30
struct profile {
     int pl_num;
     char name[LGT];
     char lname[LGT];
     int atbat[LGT/3];
     int hits[LGT/3];
     int walks[LGT/3];
     int runs[LGT/3];
     float batavg;
};

//It's wrong obviously but it's a starting point
int main(void)
{
    FILE *flx;
    int i,jc,flow=0;
    struct profile stat[LGT]={{0}};

    if((flx=fopen("team.txt","r"))==NULL) {
        fprintf(stderr,"Can't read file team!\n");
        exit(1);      
    }

    for( jc = 0; jc < 11;  jc++) {
        fscanf(flx,"%d",&i);
        stat[i].pl_num=i;

        fscanf(flx,"%s",&stat[i].name);
        fscanf(flx,"%s",&stat[i].lname);

        fscanf(flx,"%d",&stat[i].atbat[flow]);
        fscanf(flx,"%d",&stat[i].hits[flow]);
        fscanf(flx,"%d",&stat[i].walks[flow]);
        fscanf(flx,"%d",&stat[i].runs[flow]);
        flow++;
    }
}
#定义LGT 30
结构配置文件{
int pl_num;
字符名[LGT];
字符名称[LGT];
int atbat[LGT/3];
整数命中率[LGT/3];
国际步行[LGT/3];
整数运行[LGT/3];
浮动batavg;
};
//这显然是错误的,但这是一个起点
内部主(空)
{
文件*flx;
int i,jc,flow=0;
结构配置文件stat[LGT]={{0};
if((flx=fopen(“team.txt”,“r”))==NULL){
fprintf(stderr,“无法读取文件组!\n”);
出口(1);
}
对于(jc=0;jc<11;jc++){
fscanf(flx、%d、&i);
stat[i].pl_num=i;
fscanf(flx、%s、&stat[i].name);
fscanf(flx、%s、&stat[i].lname);
fscanf(flx、%d、&stat[i].atbat[flow]);
fscanf(flx,“%d”,&stat[i]。点击[flow]);
fscanf(flx、%d、&stat[i].walks[flow]);
fscanf(flx、%d、&stat[i]。运行[flow]);
flow++;
}
}

编程的第一条规则:分而治之

因此,您需要确定各个操作。一个这样的操作是“加载一行输入”,另一个是“查找播放器”。如果您有这些操作中的一些操作(在执行过程中会出现更多操作),您可以开始构建您的程序:

while( more_input ) {
    row = load_one_row()
    player = find_player( row.name )
    if( !player ) {
        player = create_player( row.name )
        add_player( player )
    }

    ... do something with row and player ...
}
当你有了它,你就可以开始写所有的函数了

这里的一个要点是编写测试用例。从一个简单的输入开始,测试代码以读取一行。你得到正确的结果了吗

如果是这样,请测试代码以查找/创建玩家

测试用例确保您可以忘记已经工作的代码


使用这样的框架。

如果我这样做,我会从一个只包含一组数据的结构开始,然后创建这些结构的数组:

struct profile {
     char name[NAMELEN];
     char lname[NAMELEN];
     int atbat;
     int hits;
     int walks;
     int runs;
     float batavg;
};
由于您使用玩家的号码作为数组的索引,因此不需要将其存储到结构中


我认为这会使问题简化一点。你不需要为一个玩家存储多个数据项——当你得到一个副本时,你只需忽略一些新数据(比如名字,应该是相同的),然后将其他数据汇总(例如,击球时,击球时)。

建议1:不要像
atbat[LGT/3]
那样声明数组

建议2:您可以在一次快照中读取整行内容,而不是多个
fscanf

建议3:由于玩家数量有限,且玩家数量的范围很广(0-18),因此使用该玩家数量作为结构数组的索引是一个好主意

建议4:因为您需要每个玩家的累积数据(不需要存储他的历史点数),所以您不需要整数数组,只需要一个整数来表示总数

因此:

#包括
#定义第19号玩家
类型定义结构
{
字符名[20+1];
char lastName[25+1];
int atbat;
整数命中率;
国际步行;
整数运行;
浮动batavg;
}轮廓;
int main(int argc,字符**argv)
{
个人资料统计[玩家编号];
int i;
文件*数据文件;
int playerNo;
配置文件tmpProfile;
整数游戏=0;

对于(i=0;我必须验证:如果我要为你打印这个列表,你能用纸和笔解决这个问题吗?如果不能,你不懂什么?如果可以,你不懂为你编写代码的什么?正如我说的,我是一个初学者,这就是我能对你说的,要么给出一些轨迹,要么就不用麻烦了!哇,冷静点,ta深呼吸……呼气。特别是初学者问家庭作业问题时,很高兴知道他们是否掌握了手头的问题并且很难将其翻译成代码,或者
struct profile {
     char name[NAMELEN];
     char lname[NAMELEN];
     int atbat;
     int hits;
     int walks;
     int runs;
     float batavg;
};
#include <stdio.h>

#define PLAYERS_NO  19

typedef struct  
{
     char name[20+1];
     char lastName[25+1];
     int atbat;
     int hits;
     int walks;
     int runs;
     float batavg;
} Profile;



int main(int argc, char** argv)
{
    Profile stats[PLAYERS_NO];
    int i;
    FILE* dataFile;

    int playerNo;
    Profile tmpProfile;
    int games = 0;


    for(i=0; i<PLAYERS_NO; ++i)
    {
        stats[i].name[0] = '\0';
        stats[i].lastName[0] = '\0';
        stats[i].atbat = 0;
        stats[i].hits = 0;
        stats[i].walks = 0;
        stats[i].runs = 0;
    }

    dataFile = fopen("team.txt", "r");
    if ( dataFile == NULL )
    {
        fprintf(stderr, "Can't read file team!\n");
        exit(1);    
     }

     for(i=0; i<PLAYERS_NO && !feof(dataFile); ++i, ++games)
     {
        fscanf(dataFile, "%d", &playerNo);
        if ( playerNo <0 || playerNo > PLAYERS_NO )
        {
           fprintf(stderr, "Player number out of range\n");
           continue;
        }

        fscanf(dataFile, "%s %s %d %d %d %d", 
            &tmpProfile.name,
            &tmpProfile.lastName,
            &tmpProfile.atbat,
            &tmpProfile.hits,
            &tmpProfile.walks,
            &tmpProfile.runs);

        printf("READ: %d %s %s %d %d %d %d\n", 
            playerNo,
            tmpProfile.name,
            tmpProfile.lastName,
            tmpProfile.atbat,
            tmpProfile.hits,
            tmpProfile.walks,
            tmpProfile.runs);


        strcpy(stats[playerNo].name, tmpProfile.name);
        strcpy(stats[playerNo].lastName, tmpProfile.lastName);

        stats[playerNo].atbat += tmpProfile.atbat;
        stats[playerNo].hits += tmpProfile.hits;
        stats[playerNo].walks += tmpProfile.walks;
        stats[playerNo].runs += tmpProfile.runs;
    }

    /* exercise: compute the average */
    fclose(dataFile);

    for(i=0; i<PLAYERS_NO; ++i)
    {
        if ( stats[i].name[0] == '\0' )
            continue;

        printf("%d %s %s %d %d %d %d\n",
            i,
            stats[i].name,
            stats[i].lastName,
            stats[i].atbat,
            stats[i].hits,
            stats[i].walks,
            stats[i].runs);
    }

    return 0;
}