读取管道分隔文件*到结构C的数组中

时间:2017-08-04 19:11:03

标签: c structure

该程序假设将管道分隔文件读入结构数组。

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

#define LEN_LINE 160
#define LEN_NAME 40
#define MAX_LINES 60
#define LEAGUE_NAME 5
#define PARK_NAME 35
#define TEAM_ADDRESS 40
#define TEAM_CITY 30
#define TEAM_STATE 5
#define ZIP_CODE 10
#define PHONE_NUMBER 30
#define WEB_ADDRESS 25
#define LEN_TEAM 60

typedef struct
{
    char leagueName[LEAGUE_NAME + 1];
    char teamName[LEN_NAME + 1];
    char parkName[PARK_NAME + 1];
    char teamAddress[TEAM_ADDRESS + 1];
    char teamCity[TEAM_CITY + 1];
    char teamState[TEAM_STATE + 1];
    char zipCode[ZIP_CODE + 1];
    char phoneNumber[PHONE_NUMBER + 1];
    char webAddress[WEB_ADDRESS + 1];


} team_t;

void displayTeams( team_t teams[], int count);

int main( void )
{
    team_t teams[LEN_TEAM] = { 0 };
    FILE *filePtr;
    int index, count;
    char line[LEN_LINE + 1] = {0};
    char *startPtr, *endPtr;

    filePtr = fopen( "MLBteams.txt", "r" );
    if ( filePtr == NULL )
    {
        printf("Error in opening file\n");
    }
    else
    {
        index = 0;
        while ( index < LEN_TEAM && fgets( line, sizeof( line ), filePtr ) )
        {
            startPtr = line;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].leagueName, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].teamName, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].parkName, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].teamAddress, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].teamCity, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].teamState, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].zipCode, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].phoneNumber, startPtr, endPtr - startPtr );

            startPtr = endPtr + 1;
            endPtr = strchr(startPtr, '|');
            strncpy( teams[index].webAddress, startPtr, endPtr - startPtr );



            index++;
        }

        fclose( filePtr );
        count = index;

        displayTeams(teams, count);
    }

    return 0;
}

void displayTeams( team_t teams[], int count)
{
    int index;

    for ( index = 0; index <= count - 1; index = index + 1)
    {
                printf("LEAGUE: %s\nTEAM: %s\nPARKNAME: %s\nADDRESS: %s\nCITY: %s\nSTATE: %s\nZIPCODE: %i\nPHONE#: %s\nWEBADDRESS: %s\n\n",
                                                     teams[index].leagueName, teams[index].teamName, teams[index].parkName,
                                                     teams[index].teamAddress, teams[index].teamCity, teams[index].teamState,
                                                     teams[index].zipCode, teams[index].phoneNumber, teams[index].webAddress);
    }
}

我正在使用它来尝试阅读此文件。

A|Baltimore Orioles|Oriole Park|333 West Camden Street|Baltimore|MD|21201|(410) 685-9800|orioles.com
A|Boston Red Sox|Fenway Park|4 Yawkey Way|Boston|MA|02215|(617) 267-9440|redsox.com
N|St. Louis Cardinals|Busch Stadium|700 Clark Street|St. Louis|MO|63102|(314) 345-9600|cardinals.com
N|Washington Nationals|Nationals Park|1500 South Capitol Street, SE|Washington|DC|20003-1507|(202) 675-6287|nationals.com

以下是几行(共30支球队)。好吧,当我运行该程序时,它立即崩溃,并没有给我任何错误消息。如果有人可以向我解释为什么代码不起作用,我将不胜感激。我的猜测是我正在使用strncpy函数错误。

2 个答案:

答案 0 :(得分:1)

在给定的代码中,保留原始字符串似乎并不重要。我建议修改它以使用strtok(),它通过在其中粘贴NUL来修改原始字符串。具体来说,它将NUL字符放在找到第一个分隔符的位置,因此您可以使用strcpy来复制该令牌。然后使用NULL的strtok将返回到原始字符串并为您找到下一个标记。在网上阅读关于strtok()的所有信息。

while (index < LEN && fgets(line, sizeof(line), filePtr))
{
   char* token = strtok(line, "|");
   strcpy(teams[index].leagueName, token);
   token = strtok(NULL, "|");
   strcpy(teams[index].parkName, token);
   // and so forth
}

现在我没有解决的问题,你应该,提供的文本对于字段来说可能太长,你的原始代码和我建议的代码都没有解决这个问题。也许

token = strtok(line, "|");
if (strlen(token) > LEAGUE_NAME) token[LEAGUE_NAME]=0;
strcpy(teams[index].leagueName, token);

同样是你的strchr()结果,并且在上面的原型代码中,没有检查strtok()结果。如果输入行比预期宽,那么受限制的fgets()调用可能会截断该行并省略分隔符。 strchr或strtok结果将为NULL,这将阻止您的程序。

答案 1 :(得分:0)

你猜对了!在这种情况下,您需要手动'\0'终止字符串,因此即使在清晰度方面,使用memcpy()可能会更好。

string[endPtr - startPtr] = '\0';

对于每个 string