2012-03-08 3 views
2

Текстовый файл содержит информацию о команде софтбола. Каждая строка содержит данные, расположенные следующим образом:C Primer 5th - Task 14-6

4 JESSIE Joybat 5 2 1 1

Первый элемент является номером игрока, обычно в диапазоне 0-18. Второй элемент - имя игрока, а третья - фамилия игрока. Каждое имя - это одно слово. Следующий пункт - это официальные времена игрока на летучей мыши, за которым следует количество хитов, прогулок и пробегов в матче (ИКР). Файл может содержать данные для более чем одной игры, поэтому у одного и того же игрока может быть более одной строки данных, и могут быть данные для других игроков между этими линиями. Напишите программу, которая хранит данные в массиве структур. Структура должна иметь членов для представления имени и фамилии, бит летучих мышей, хитов, прогулок и ИКР (работает с ошибкой) и среднего значения ватин (для расчета позже). Номер игрока можно использовать как индекс массива. Программа должна читать до конца файла, и она должна содержать кумулятивные итоговые значения для каждого игрока.

Мир бейсбольной статистики - это задействованный. Например, прогулка или достижение базы при ошибке не засчитывается как бит-бит, но может привести к созданию RBI. Но все, что нужно сделать этой программе, - это прочитать и обработать файл данных, как описано ниже, не беспокоясь о том, насколько реалистичны данные.

Самый простой способ для продолжения программы - инициализировать содержимое структуры нулями, прочитать данные файла во временные переменные и затем добавить их в содержимое соответствующей структуры. После того, как программа закончит чтение файла, он должен затем вычислить среднее значение ватин для каждого игрока и сохранить его в соответствующем члене структуры. Среднее значение ватин рассчитывается путем деления совокупного количества обращений игрока на кумулятивное количество бит-бит; это должен быть расчет с плавающей запятой. Затем программа должна отображать кумулятивные данные для каждого игрока вместе с линией, показывающей комбинированную статистику для всей команды.


team.txt (текстовый файл, я работаю с):

4 Jessie Joybat 5 2 1 1 
4 Jessie Joybat 7 3 5 3 
7 Jack Donner 6 3 1 2 
11 Martin Garder 4 3 2 1 
15 Jaime Curtis 7 4 1 2 
2 Curtis Michel 3 2 2 3 
9 Gillan Morthim 9 6 6 7 
12 Brett Tyler 8 7 4 3 
8 Hans Gunner 7 7 2 3 
14 Jessie James 11 2 3 4 
12 Brett Tyler 4 3 1 3 

Так как я новичок в 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++; 
    } 
} 
+2

Просто проверить: Если бы я был напечатать этот список для вас, вы могли бы решить эту проблему с ручкой и бумагой? Если нет, что вы не понимаете? Если бы вы могли, что вы не понимаете о написании кода, чтобы сделать это за вас? – Bart

+0

Как я уже сказал, я новичок, это все, что я могу сказать вам, либо дать несколько треков, либо не беспокоить! – highlevelcoder

+0

Ничего себе, успокойтесь, сделайте глубокий вдох ... выдохните. Особенно, когда начинающие задают домашние вопросы, приятно знать, понимают ли они проблему и просто испытывают трудности с ее переводом в код или если они еще не поняли, что именно они просят сделать. Я просто пытался проверить, кто из этих двух, потому что они требуют разных ответов. Кроме того, мой опыт показывает, что надежные старые ручки и бумага слишком мало используются новыми программистами, которые часто увязли, пытаясь запрограммировать свой выход из проблемы. Как только вы действительно высокого уровня, вы получите это. – Bart

ответ

1

Совет 1: не объявлять массивы, как atbat[LGT/3].

Совет 2: Вместо нескольких fscanf вы можете прочитать всю строку в кадре.

Совет 3: Поскольку количество игроков ограничено, а номер игрока имеет хороший диапазон (0-18), использование этого номера игрока в качестве индекса в массиве struct является хорошей идеей.

Совет 4: Поскольку вам нужны кумулятивные данные для каждого игрока (нет необходимости хранить его точки истории), тогда вам не нужны массивы целых чисел, а всего целые числа для представления общего числа.

Итак:

#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; 
} 
+0

Я изменил «memset» с помощью цикла, потому что это домашнее задание. «Memset», вероятно, более чистый и быстрый: 'memset (stats, 0, sizeof (Profile) * PLAYERS_NO);' – vulkanino

0

Первое правило программирования: разделяй и властвуй.

Таким образом, вам необходимо идентифицировать отдельные операции. Одной из таких операций является «загрузка одной строки ввода», другая - «поиск игрока». Если у вас есть некоторые из этих операций (более придумает, как вы идете), вы можете начать строить свою программу:

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 ... 
} 

, когда у вас есть, что вы можете начать писать все функции.

Важным моментом здесь является создание тестовых примеров. Начните с простого ввода и проверьте код для чтения строки. Получаете ли вы правильные результаты?

Если это так, проверьте код, чтобы найти/создать игроков.

В тестовых случаях убедитесь, что вы можете забыть о коде, который уже работает.

Для этого используйте каркас, такой как Check.

0

Если бы я делал это, я бы начал со структурой, которая только состоявшейся один «набор» данных, а затем создать массив этих структур:

struct profile { 
    char name[NAMELEN]; 
    char lname[NAMELEN]; 
    int atbat; 
    int hits; 
    int walks; 
    int runs; 
    float batavg; 
}; 

Поскольку вы используете номер игрока как индекс в массив, вам не нужно также хранить его в структуре.

Я думаю, что это немного упростит проблему. Вам не нужно хранить несколько элементов данных для одного игрока - когда вы получаете дубликат, вы просто игнорируете некоторые новые данные (например, имена, которые должны быть идентичны) и суммируйте остальные (например, летучие мыши, хиты).

Смежные вопросы