在C中打印字符指针 - 我不断格式化

时间:2010-09-26 17:26:14

标签: pointers fstream strtok file-read

我正在从包含人名的文件中读取一行,第一行包含男性名称,秒行包含女性名称。然后我想把这些名字存储在两个数组中,一个用于男性,一个用于女性,但是当我打印它们时,我会得到奇怪的东西。我不确定我是不是正确阅读它们,还是不正确地打印它们

    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

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

3 个答案:

答案 0 :(得分:2)

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

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

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

如果您的输入或输出中存在问题,则会通知您。或者,使用调试器逐步完成循环,看看到底发生了什么。

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

答案 1 :(得分:1)

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

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

答案 2 :(得分:1)

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

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

除了空格之外,我更改了分隔符以包含\ 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;
}