3

我有一个名为 Players.txt 的文件,其中包含

皮耶罗|3|意大利|尤文图斯罗纳尔多|0|葡萄牙|皇家马德里

我想将每个病房读入一个单独的数组,例如要包含的数组播放器
players[NUM_PLAYERS][NAME_LENGTH]={ Del Piero,Ronaldo}
等与其他数组,

我知道它需要使用一个名为 fgets 的函数和一些字符串函数。

这是我尝试过的;我的问题是:有没有其他方法可以解决我的问题,比如使用一些不同的程序或字符串程序?以及如何从这个文件中获取目标数量并将它们存储到文件中

#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;
}
4

3 回答 3

2

您可以尝试使用 fscanf,而不是 fgets+strchr。然后您将获得更简单的代码和更高的安全性(现在您的代码很容易溢出缓冲区,导致不可预知的结果)。

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

注意:该模式非常特定于您的数据格式,从您的问题来看,我不清楚 country_name 的分隔符(如果有的话)是什么。然后最后一个字符串模式是通常的%s,首先停止space

于 2013-07-09T16:50:57.687 回答
0

我建议使用映射:这样您就可以将文件的全部内容直接放入可寻址内存中,从而让您可以在闲暇时检查数据。

作为额外的好处,如果您在对 mmap() 的调用中指定 MAP_PRIVATE,您可以简单地将其剪切成单独的字符串(用空字节替换 '|' 和 '' 字符)而不修改文件。这使您不必复制字符串。剩下的就是在数据中构建索引结构的简单问题。

这是我使用的骨架:

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

请注意,当映射存在时,不必保持文件打开。

就性能而言,这可能是您可以实现的最佳效果,因为整个过程可以在不制作数据的单个副本的情况下发生,从而节省了 CPU 时间和内存。

于 2013-07-09T17:01:56.847 回答
0

我建议在您的代码中使用fscanf而不是使用。fgets

详细的fscanf参考和使用文档,请参见:http ://www.cplusplus.com/reference/cstdio/fscanf/

于 2013-07-09T16:54:39.960 回答