试图解析文档和存储节点信息,不知道为什么它的segfaulting

时间:2013-11-20 01:00:03

标签: c parsing file-io

当我gdb程序时,它说strcpy有问题,但我不知道为什么。 感谢。

该程序要求我阅读输入文件,查找课程缩写,课程说明,学分时数和教授姓名。

另外,我正在尝试从文件中读取学分,这与课程在同一行。我试图只获得与课程在同一行的学分,但它会将每个数字打印为学分。

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

#define MAX 20

typedef struct courses{
    char *abbr;
    char *name;
    int credits;
    char *prof;
    struct courses *next;
}courses;

int isAbbr(char *string);
int isName(char *string);
int isCredit(char *string);
int isProf(char *string);
courses *readfile(FILE *);
courses *create_course(char *abbr, char *name, int credits, char *prof);
courses *create_list(courses *, courses *);

int main(int argc, char **argv)
{
    if (argc != 2)
    {
            printf("Inadequate amount of arguments.\n");
            return 0;
    }
    FILE *fp = fopen(argv[1], "r");
    if (fp == NULL)
    {
            printf("File cannot be opened.\n");
            return 0;
    }

    courses* head = NULL;
    head = readfile(fp);

    int choice = 0;
    while (choice != 3)
    {
            printf("\nSelect your option below:\n1-Register for a Course\n2-See my      total\n3-Exit\nChoice: ");
            scanf("%d",&choice);
    }

    return 0;
}

courses *readfile(FILE *fp)
{
    courses *head, *entry;
    head = entry = NULL;

    char *abbr = malloc(MAX);
    char *namep = malloc(MAX);
    namep = "hello";
    char *prof = malloc(MAX);
    int credit;
    int credflag = 0;
    int nameFlag = 0;
    int profFlag = 0;
    int credits = 0;

    char line[MAX];
    while (fgets(line, MAX - 1, fp) != NULL)
    {
            if (line[strlen(line) - 1] == '\n')
            {
                    line[strlen(line) - 1] = '\0';
            }
            char* token = strtok(line," ,\t");
            while (token != NULL)
            {
                    if (isAbbr(token) == 1)
                    {
                            abbr = token;
                            credflag = 1;
                    }
                    if (isName(token) == 1)
                    {
                            credflag = 1;
                    }
                    if (isCredit(token) == 1)
                    {
                            if(credflag == 1)
                            {
                                    credits = atoi(token);
                                    credflag = 0;
                            }
                    }
                    if (isProf(token)== 1)
                    {
                            if(nameFlag == 1) //print names, reset name flag = 0
                            {
                                    entry = create_course(abbr, namep, credits, token);
                                    head = create_list(entry,head);
                                    nameFlag = 0;
                            }
                            else
                            {
                                    namep = malloc(sizeof(char));
                                    strcpy(namep, token);
                                    nameFlag = 1;
                            }
                    }
                    else
                    {
                            nameFlag = 0;
                    }
                    token = strtok(NULL," ,\t");
            }
    }
}

courses *create_course(char *abbr, char *name, int credits, char *prof)
{
    courses *entry = malloc(sizeof(courses));

    entry->abbr=(char*)malloc(sizeof(char)*256);
    strcpy(entry->abbr, abbr);

    entry->name=(char*)malloc(sizeof(char)*256);
    strcpy(entry->name, name);

    entry->abbr=(char*)malloc(sizeof(char)*256);
    strcpy(entry->prof, prof);

    entry->credits = credits;
    entry->next = NULL;

    return entry;
}

courses *create_list(courses *head, courses *entry)
{
    if (head == NULL)
    {
            return entry;
    }
    courses* curr = head;
    while (curr->next != NULL)
    {
            curr = curr->next;
    }
    curr->next = entry;
    return head;
}

int isProf(char *string)
{
    int length = strlen(string);
    int i;
    if (isupper(string[0]))
    {
            for (i=1; i<length; i++)
            {
                    if (islower(string[i]))
                    {
                            continue;
                    }
                    else
                    {
                            return 0;
                    }
            }
            return 1;
    }
}

int isCredit(char *string)
{
    int n;
    int nfields = sscanf(string, "%d", &n);
    if (nfields == 1 && n > 0)
    {
            return 1;
    }
    return 0;
}

int isName(char *string)
{
    return 1;
}

int isAbbr(char *string)
{
    int length = strlen(string);
    if (length == 8 && string[4] == '-')
    {
            printf(" %s\n",string);
            return 1;
    }
    return 1;
}

1 个答案:

答案 0 :(得分:0)

只关注strcpy:

char *namep = malloc(MAX);
namep = "hello";

这里你只丢失了你的malloc for namep,使用strcpy或你想要的东西。

namep = malloc(sizeof(char));
strcpy(namep, token);

这里你只是malloc 1 char为namep,但是strcpy auto添加NULL终止符,所以除非token是“”,否则你溢出namep。

在create_course()中的每个strcpy,你只需要malloc 256和strcpy,如果大小为abbr,name,prof&gt; 255?检查大小或使用strncpy()。