0

我正在从包含人名的文件中读取一行,第一行包含男性姓名,第二行包含女性姓名。然后我想将这些名字存储在两个数组中,一个用于男性,一个用于女性,但是当我打印它们时,我得到了奇怪的东西。我不确定我是否没有正确阅读它们,或者打印不正确

    char line[100];      //holds line read
    char *item;         //item in a line
    char *item2;
    int participants = 5;   //number of people in the event

            char* maleNames[participants];
            char* femaleNames[participants];

            fgets(line, 255, file);
            int i;
            item = strtok(line, " ");
            for(i=0; i<participants; i++)
            {
                maleNames[i] = item;  
                item = strtok(NULL, " ");


               }

        //read female names now
        fgets(line, 1024, file);
        item2 = strtok(line, " ");
        for(i=0; i<participants; i++)
        {
            femaleNames[i] = item2;
            item2 = strtok(NULL, " ");
        }

这些行被读取

John Jeffrey Adam Mark Peter
Jenny Alice Sally Wendy Amanda

但是,当我像这样打印它们时:

        for(i=0;i<participants;i++)
        {
            printf("%s %s\n", maleNames[i], femaleNames[i]);
        }

我得到了如此不同的东西:

Jenny Jenny
 Alice
ally Sally
Wendy Wendy
 Amanda

注意:如果我在阅读女性姓名之前在阅读男性姓名后立即打印男性姓名,那么它们会正确打印

4

3 回答 3

2

首先(且不相关):您声明linechar[100]; 但是,您正在使用fgets(line, 1024, file)and fgets(line, 255, file)- 这些是等待发生的缓冲区溢出。

接下来,确定读取令牌时会发生什么。例如,我会这样做:

for(i=0; i<participants; i++)
{
    maleNames[i] = item;
    printf("Token %d: %s", i, item);
    item = strtok(NULL, " ");
}

这将让您知道您的输入或输出是否有问题。或者,使用调试器单步执行循环,并准确查看那里发生了什么。

此外,我认为您需要将 的返回值复制strtok到另一个字符数组中。查看strdup复制您的字符串。

于 2010-09-26T17:37:33.143 回答
1

不注意其他问题(例如大小,255 和 1024,当您的缓冲区只有 100 个字符长时传递给 fgets),这个问题很可能来自您使用相同的缓冲区,char line[100] , 对于 fgets() 的两个调用。Strtok 返回一个指向行缓冲区中的字符的指针,因此当您将女性姓名存储在“行”中时,所有这些指针(相对于行包含男性姓名的行)现在都无效。尝试将母线存储在其他缓冲区中,它应该可以工作。

编辑:对不起,如果“不注意......”听起来令人沮丧。没有什么比我的意图更远了。每个人每次都会犯错,尤其是在学习的时候。我祝你在这个过程中好运:)

于 2010-09-26T17:36:54.253 回答
1

正如@lacqui 已经提到的,你有潜在的缓冲区溢出。我将 fgets 更改为传递 sizeof(line1)-1 而不是硬编码值。这样,编译器将计算出要传递的大小......即使您后来决定增加/减少缓冲区大小。负 1 是这样 fgets 不会在最后覆盖空终止符。我还使用 memset 初始化缓冲区。

我还添加了另一个行缓冲区,因为 strtok通过用 null 替换指定的分隔符字符并返回指向该字符串中的标记位置的指针来修改字符串...... strtok 不会复制。

我将分隔符更改为除了空格之外还包括 \r 和 \n。

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

int main() {
   char line1[100];      //holds line read
   char line2[100];
   char *item;         //item in a line
   char *item2;
   const int participants = 5;   //number of people in the event

   char* maleNames[participants];
   char* femaleNames[participants];

   FILE* file = fopen("names.txt", "r");

   memset(line1, 0, sizeof(line1));
   fgets(line1, sizeof(line1)-1, file);

   int i;
   item = strtok(line1, " \r\n");
   for(i=0; i<participants; i++)
   {
      maleNames[i] = item;  
      item = strtok(NULL, " \r\n");
   }

   //read female names now
   memset(line2, 0, sizeof(line2));
   fgets(line2, sizeof(line2)-1, file);

   item2 = strtok(line2, " \r\n");
   for(i=0; i<participants; i++)
   {
      femaleNames[i] = item2;
      item2 = strtok(NULL, " \r\n");
   }

   for(i=0;i<participants;i++)
   {
      printf("%s %s\n", maleNames[i], femaleNames[i]);
   }

   return 1;
}
于 2010-09-26T18:01:10.850 回答