2017-02-09 20 views
1

割り当てに問題があります。ファイルから構造体を読み込み、ここでどのように行うのか混乱しています。使用するパラメータがある関数です。複数のファイルから構造体を読み込む

// This function will read in size struct players from filename and add these 
// the players array. The function will use index to know where to start 
// writing the players to in the array. 
// Parameters 
// 
// filename – The name of the input file 
// players – a pointer to the array of player structures 
// index – The index of the array to start placing players into 
// size – The number of players in the input file 
// Return - Nothing 

void read_from_file(char* filename, Player* players, int index, int size); 

これは私のような見て、3種類のファイルからデータを読み込むために使用しなければならない機能です:

Andrew Jackson 129 33 38 30 506 
Jeremy Warden 25 24 3 9 493 
Jared Welch 130 1 43 27 422 
Brandon Splitter 138 38 40 7 587 
Joe Gwilliams 150 23 30 25 498 
Ali Mohammed 119 43 13 6 598 
Dheeraj Johnson 124 79 59 36 506 
Bill Clinton 121 65 12 26 449 
Jesse James 87 58 8 5 464 
John Doe 129 100 0 12 548 

私はすべてのためにそれらに10人の選手を持っている3つのファイルを読み込む必要はあり合計30の構造を読み込む必要があります。私は非常に遠くまで私は知っていないが、私は何をすべきか、どのようにこれにアプローチするのが非常に混乱している、どんな助けも非常に高く評価されるだろう!下に私はすでに行っていることをダウンしている。助けてください!!おかげ

//Brady Webb 
//lab D 
//HW1 

#include<stdio.h> 
#include<string.h> 
#include<stdlib.h> 

typedef struct player 
{ 
    char Fname[25]; 
    char Lname[25]; 
    int Singles; 
    int Doubles; 
    int Triples; 
    int Homeruns; 
    int At_Bats; 
    float Slugging_Percentage; 
} Player; 

void read_from_file(char* filename, Player* players, int index, int size); 

int main(int argc, char* argv[]) 
{ 
    int size= atoi(*(argv+1)); 
    char* file1 = *(argv+2); 
    char* file2 = *(argv+3); 
    char* file3 = *(argv+4); 
    if (argc<6 || argc>6) 
    { 
     printf("Incorrect command line arguments\n"); 
     return 0; 
    } 

    return 0; 
} 
void read_from_file(char*filename, Player* players, int index, int size) 
{ 
    FILE *ptr; 
    int i=0; 

    if ((ptr=fopen(filename, "r")) == NULL) 
    { 
     return 0; 
    } 

    while (ptr != EOF) 
    { 

    } 

} 
+0

「argv + 5」についてはどうですか? argv + 1から得られる値の意味は? 'if(argc!= 6)' – user3629249

+0

エラーメッセージは 'stdout'ではなく' stderr'に出力されなければなりません。次の行は 'if(argc <6 || argc> 6)です。したがって、次の行: 'printf("不正なコマンドライン引数\ n ");'は、実際には 'fprintf(stderr、"不正なコマンドライン引数\ n ");' – user3629249

+0

プログラムに属していない場合は、 'argc' FIRSTの値をチェックし、有効な場合にのみ個々の引数を取得します。 – user3629249

答えて

2

規則的な構造を持つファイルを読み込むための最も簡単な方法は、複雑な形式の文字列でfscanfを使用することです。

fscanf("%s %s %d %d %d %d %d", Player.Fname, Player.Lname, 
          &Player.Singles, &Player.Doubles, 
          &Player.Triples, &Player.Homeruns, &Player.At_Bats); 

あなたはまで、ファイルの読み取りにループを作る必要があり、あなたは、正しい形式でデータを読み込むのチェックを追加することができます。例:

int check = fscanf("%s %s %d %d %d %d %d", Player.Fname, Player.Lname, 
          &Player.Singles, &Player.Doubles, 
          &Player.Triples, &Player.Homeruns, &Player.At_Bats); 
if(check != 7) 
{ 
    // stop reading and report on wrong file format 
} 

UPDATE:

// This function will read in size struct players from filename and add these 
// the players array. The function will use index to know where to start 
// writing the players to in the array. 
// Parameters 
// 
// filename – The name of the input file 
// players – a pointer to the array of player structures 
// index – The index of the array to start placing players into 
// size – The number of players in the input file 
// Return - number of read players (positive number) 
//   or error code (negarive number) 
int read_from_file(char * filename, Player* players, int index, int size) 
{ 
    struct player ptmp; 
    FILE *fptr; 
    // open the file 
    if ((fptr = fopen(filename, "r")) == NULL) 
    { 
     fprintf(stderr, "File %s cannot be oppened\n",filename); 
     return -1; // error code for "File cannot be oppened" 
    } 
    // reading from file 
    int position = index; 
    int cnt = 0; 
    while (!ferror(fptr) && cnt < size) 
    { 
     int check = fscanf(fptr, "%24s %24s %d %d %d %d %d", ptmp.Fname, ptmp.Lname, 
      &ptmp.Singles, &ptmp.Doubles, &ptmp.Triples, &ptmp.Homeruns, &ptmp.At_Bats); 
     if (feof(fptr) && check != 7) 
     { 
      break; 
     } 
     if (check != 7) 
     { 
      fclose(fptr); 
      fprintf(stderr,"Wrong data format in line %d of file %s\n", cnt+1, filename); 
      return -2; // error code for "File has wrong data format" 
     } 
     // copy data to players 
     players[index++] = ptmp; 
     cnt++; 
    } 
    // close the file 
    fclose(fptr); 
    return cnt; 
} 

は、私は可能な解決策として、次のコードを提案します

変更された関数のタイプに注意してください。read_from_file - コメントの戻り値に関する私の考えを説明しました。各ファイルの10に、必ずしもではない30人の選手は、任意の数のファイルを読み取ることができるものとされており、

int main(int argc, char* argv[]) 
{ 
    Player players[30]; // memory is allocated for particular number of data items 
    // check the command line arguments 
    if (argc < 3) 
    { 
     printf("Please run the program in the format:\n"); 
     printf(" %s 2 firstFile.txt secondFile.txt\n", argv[0]); 
     printf(" where 2 is number of files given after 2 with data to be read\n"); 
     return 0; 
    } 
    int fileNumber = 0; 
    if (!sscanf(argv[1], "%d", &fileNumber) || fileNumber <= 0) 
    { 
     printf("The first command line argument nust be positive number.\n"); 
     printf("Run program without parameters to see details\n"); 
     return 0; 
    } 
    if (fileNumber != (argc - 2)) 
    { 
     printf("Command line arguments are inconsistent\n"); 
     printf("Run program without parameters to see details\n"); 
     return 0; 
    } 
    // file processing 
    int i = 0; 
    int total = 0; 
    int max = 30; 
    for (i = 0; i < fileNumber; i++) 
    { 
     printf("Reading from %s...\n", argv[i + 2]); 
     int res = read_from_file(argv[i + 2], players, total, max); 
     if (res > 0) 
     { 
      total += res; 
      max -= res; 
     } 
    } 
    // check data 
    for (i = 0; i < total; i++) 
    { 
     printf("%s %s : %d %d %d %d %d\n", players[i].Fname, players[i].Lname, players[i].Singles, players[i].Doubles, players[i].Triples, players[i].Homeruns, players[i].At_Bats); 
    } 
    return 0; 
} 

:私の理解で

そしてmainは次のようにする必要があります。

+0

http://stackoverflow.com/questions/5431941/why-is-while-feof-file -always-wrong –

+0

Brady Webbはループの書き方を決定する必要があります。実際に 'feof(fptr)'が他のチェックと複雑な条件で使用されている場合はそれほど間違っていないように見える – VolAnd

+0

一般に、ファイルの最後まで読み込んだときにだけアサートされるので、 'feofファイルの最後を読み取ってみてください(次の読み込み時)注:質問には何もないし、 'size'コマンドラインパラメータが次のファイル名の数を示すことを示す投稿コードにもありません。その仮定をしないことを強くお勧めします – user3629249

0

ループは、一度に1つの行を読み取るためにリターンすることができ、各ラインは、上記のコードは、ながら(PTRとしてポストコードにループを交換する必要がありgetPlayer

char *line; 
char buffer[256]; // assuming that's the longest line size 
while ((line = fgets(buffer, sizeof(buffer), ptr)) != NULL) { 
    Player *pl = getPlayer(line); 
    //... 
} 

ようなヘルパー関数に渡すことができます!= EOF)。 getPlayerは、次の線に沿って何かすること(などのプレーヤーは、リストに追加することができます/配列および設定が終了したら、あなたはそれに応じて解放してください)また、上記解決することができますトークナイザを使用して

Player *getPlayer(char *line) { 
     Player *iPlayer = (Player *)malloc(sizeof(Player)); 
     sscanf(line, "%s %s %d %d %d %d %d %f", 
       iPlayer->Fname, 
       iPlayer->Lname, 
       &iPlayer->Singles, 
       &iPlayer->Doubles, 
       &iPlayer->Triples, 
       &iPlayer->Homeruns, 
       &iPlayer->At_Bats, 
       &iPlayer->Slugging_Percentage); 
     return iPlayer; 
} 
0
struct Player PlayerArr[10]; 

void read_from_file(char*filename, Player* players, int index, int size) 
{ 
    FILE *ptr; 
    int i=0; 
    char content[50]; 

    memset(content, '\0', 50); 

    if ((ptr=fopen(filename, "r")) == NULL) 
    { 
     return 0; 
    } 

    while (ptr != EOF) 
    { 
     getline(infile,line); 
     memset(content,'\0',sizeof(content)); 
     strcpy(content,line.c_str()); 
     ReadNextConfRecord(content); 
    } 

    return 0; 
} 

int ReadNextConfRecord(char *content) 
{ 
     char str[50]; 
    const char delimiter[2] = " "; 
    char *token; 
    int count =0; 
    int i =0; 

    memset(str, '\0', 50); 

    strcpy(str, (char*)content); 

    token = strtok(str, delimiter); 
    while(token != NULL) 
    { 
    count++; 
     if(count == 1) 
      { 
       strcpy(PlayerArr[i].Fname, token); 
      } 
     else if(count == 2) 
      { 
       strcpy(PlayerArr[i].Lname, token); 
      } 
     else if(count == 3) 
      { 
       PlayerArr[i].Singles= atoi(token); 
      } 
     else if(count == 4) 
      { 
       PlayerArr[i].Doubles= atoi(token); 
      } 
     else if(count == 5) 
      { 
       PlayerArr[i].Triples= atoi(token); 
      } 
     else if(count == 6) 
      { 
       PlayerArr[i].Homeruns= atoi(token); 
      } 
     else if(count == 7) 
      { 
       PlayerArr[i].At_Bats= atoi(token); 
      } 
     else if(count == 8) 
      { 
       PlayerArr[i].Slugging_Percentage= atof(token); 
      } 
     i++;      
     token = strtok(NULL, delimiter); 
    } 
    return 0; 
} 

をすることができます問題

関連する問題