简体   繁体   中英

how to read from a file into array in c programming

I have a file called Players.txt which contains

Del Piero|3|Italy|Juventus Ronaldo|0|Portugal|Real Madrit

I want to read each ward into a separated array, like array players to contain
players[NUM_PLAYERS][NAME_LENGTH]={ Del Piero,Ronaldo}
and so on with the other arrays,

I know that it need to use a function called fgets and some string functions.

here is what i tried; My questions are : Is there any other approach to my problem, like to use some different programs, or string programs? And how to get the number of goals form this file and store them into the file

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

#define NUM_PLAYERS 20
#define NAME_LENGTH 100
#define COUNTRY_NAME 20


int main (void)    
{    
    FILE *Players;    

    char player_name [NUM_PLAYERS][NAME_LENGTH] = {0};
    char team_name[NUM_PLAYERS][NAME_LENGTH] = {0};
    char country_name[NUM_PLAYERS][COUNTRY_NAME] = {0};

    char temp_buffer[NAME_LENGTH]={0};
    int goals_scored[NUM_PLAYERS] = {0};

    char *ptr1,*ptr2,*ptr3;
    int i;

    Players = fopen("Players.txt", "r");
    if (Players == NULL)
    {
        printf("File not found.\n");
    }
    else
    {
        i=0;
        while ((fgets(temp_buffer,sizeof(temp_buffer), Players) != NULL) && i < NUM_PLAYERS)

        {
            ptr1 = strchr(temp_buffer, '|');
            strncpy(player_name[i], temp_buffer, ptr1 - temp_buffer);
            printf("the name of the player is %s\n.", player_name[i]);
            i ++;

        }       
    }
  fclose(Players);

    return 0;
}

You could try to use fscanf, instead of fgets+strchr. Then you will gain simpler code and more safeness (now your code will easily overflow the buffer, with unpredictable results).

 if (fscanf(Players, " %*[^|]|%d|%*[^|]|%*s",
     NAME_LENGTH-1, player_name[i],
     goals_scored + i,
     NAME_LENGTH-1, team_name[i],
     NAME_LENGTH-1, country_name[i]) == 4) {
   ...
 }

note: the pattern is very specific to your data format, and from your question isn't clear to me what delimiter (if any) there is for country_name. Then the last string pattern is the usual %s , that stops at first space

I suggest using fscanf instead of using fgets in your code.

For detailed fscanf reference and usage doc, see: http://www.cplusplus.com/reference/cstdio/fscanf/

I would recommend mmapping: That way you get the entire contents of the file directly into addressable memory, allowing you to examine the data at your leisure.

As an added bonus, you can simply cut it into individual strings (replacing the '|' and ' ' chars with null bytes) without modifying the file, if you specify MAP_PRIVATE in the call to mmap(). This saves you the necessity to copy the strings. The rest is a simple matter of building an index structure into the data.

This is the skeleton of what I use:

const char* mmapInputFile(const char* path, int kernelAdvice, off_t* outLength) {
    //Open the file.
    int file = open(path, O_RDONLY);
    if(file == -1) /* error handling */;
    *outLength = lseek(file, 0, SEEK_END);  //Get its size.

    //Map its contents into memory.
    const char* contents = (const char*)mmap(NULL, *outLength, PROT_READ, MAP_PRIVATE, file, 0);
    if((intmax_t)contents == -1) /* error handling */;
    if(madvise((void*)contents, *outLength, kernelAdvice)) /* error handling */;

    //Cleanup.
    if(close(file)) /* error handling */;
    return contents;
}

Note that it is not necessary to keep the file open while the mapping exists.

Performancewise this is probably the best you can achieve, because the entire process can happen without making a single copy of the data, which saves both CPU time and memory.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM