2014-09-24 87 views
1

编辑2:好的,我所做的只是将字符指向的姓氏[i]的malloc更改为50字节,而且我的程序工作正常。谁能解释为什么?我认为这是因为strtok返回一个指向大于16字节的字符串的指针,我试图将该字符串分配给动态分配的16字节数组。谢谢。 我想解析文件中的一行,并将它们存储到3个并行数组中。我从阅读的文本文件中有这样的吧:不太确定为什么strtok不按我想要的方式工作

瑞安,伊丽莎白O. \ n 麦金太尔,OJ \ n Cauble-Chantrenne,克里斯汀K. \ n 拉森,伊丝F. \ n 索普,三位一体R. \ n Ruiz的,佩德罗M. \ n

对每个人的格式是姓,姓名/初始,中间和初始 我有3个平行阵列:字符**姓,焦炭**第一和char * middle_init 我已经检查过我对Fgets的调用是否工作。我的算法是先将每行存储到surname [i]中,然后将其解析为其组件,然后将其解析为3个并行数组。

问题: 我的程序有效,但由于某种原因,它不适用于“Cauble-Chantrenne,Kristin K.”。当我打印出来的姓氏[2]和第[2],我得到: Cauble-Chantren KristLarson

int main(int argc, char *argv[]) { 
    char **surname, **first; 
    char *middle_init; 
    int num_people; 
    FILE *fp = fopen(argv[1], "r"); 
    fscanf(fp, "%d", &num_people); 
    surname = (char**)malloc(sizeof(char*) * num_people); 
    first = (char**)malloc(sizeof(char*) * num_people); 
    middle_init = (char*)malloc(sizeof(char) * num_people); 
    read_names(fp, num_people, surname, first, middle_init); 
    fclose(fp); 
    printf("%s\n", surname[2]); 
    printf("%s\n", first[2]); 
    sort(num_people, surname, first, middle_init); 
    write_names(num_people, argv[2], surname, first, middle_init); 
    return 0; 
} 

有人能告诉我我的问题是什么?谢谢!!!我相信我的问题与我的代码的这部分有关。附:据我所知,strtok返回一个指向该标记的指针并自动将'\ 0'放置正确?为什么第一[2]不是克里斯汀?它显然被2个分隔符分隔,即“< - 空白空间。非常感谢!!真的很欣赏时间。

while(fgets(surname[i], 80, fp) != NULL) { 
    surname[i] = strtok(surname[i], ","); 
    if (strlen(surname[i]) >= 16) { 
     surname[i][15] = '\0'; 
    } 
    first[i] = strtok(NULL, ". "); 
    if (strlen(first[i]) >= 16) { 
     first[i][15] = '\0'; 
    } 
    middle_init[i] = *(strtok(NULL, ". ")); 
    i++; 
    } 

我所有的其他功能都能正常工作,我的错误只是从文件中读入数组中的数据。谢谢!

+4

可能是因为它的工作方式是_documented._如果这与你想要的方式不同,我怀疑问题在于你的结局:-) – paxdiablo 2014-09-24 06:07:06

+0

请你详细说明一下:你如何为个人分配姓氏的内存行,你的中间init数组是如何初始化的,因为它应该存储一个字符'middle_init [i] = *(strtok(NULL,“。”));' – Steen 2014-09-24 07:50:10

+0

它确实存储了一个字符。那部分工作得很好。只有我的第一个[]数组被搞乱了,因为姓氏长度大于16个字符的人。谁能帮忙? – 2014-09-24 08:54:27

回答

0

您需要将一个临时缓冲区传递到fgets,因为strtok会截取原始字符串。因此,通过使用单独的字符串来保存读取行,您将防止切断源字符串的意外结果。

此外,您的if陈述似乎很奇怪。你正在切断16字节的字符串,这可能是你想要做的,但在这个代码块中做这件事似乎很奇怪。

+0

这是该程序的规范!扫描每个姓氏和名字最多16个字符!尽管谢谢! – 2014-09-24 08:25:06

+0

你是什么意思的缓冲区? – 2014-09-24 08:25:17

+0

缓冲区只是一个字符串。 – Dan 2014-09-24 13:54:48

相关问题