在 C 中打印字符指针 - 我总是遇到错误的格式

发布于 2024-09-24 23:43:17 字数 1303 浏览 10 评论 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

注意:如果我在男性的名字被打印出来后立即打印它们在读取女性名字之前先阅读,然后正确打印

I am reading a line from a file containing the names of people, first line contains names of males, and seconds line contains names of females. Then I want to store these names in two arrays, one for males, one for females, however when I print them I get weird things. I'm not sure if I am not reading them correctly, or printing them incorrectly

    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, " ");
        }

These lines are read

John Jeffrey Adam Mark Peter
Jenny Alice Sally Wendy Amanda

However when I print them out like this:

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

I get something so different:

Jenny Jenny
 Alice
ally Sally
Wendy Wendy
 Amanda

Note: if I print the names of males right after they're read before reading the female names, then they are printed correctly

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

无悔心 2024-10-01 23:43:17

首先(且不相关):将 line 声明为 char[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 来复制字符串。

First off (and unrelated): you declare line to be char[100]; however, you are using fgets(line, 1024, file) and fgets(line, 255, file) - these are buffer overruns waiting to happen.

Next, determine what happens when you read a token. For example, I would do:

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

This will let you know if you have an issue in your input or in your output. Alternatively, step through the loop with a debugger and see exactly what's happening there.

Additionally, I believe that you need to copy the return value of strtok into another character array. Look into strdup to copy your strings.

↙温凉少女 2024-10-01 23:43:17

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

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

Not paying attention to other problems (like the size, 255 and 1024, you pass to fgets when your buffer is only 100 characters long), this problem most likely comes from the fact that you are using the same buffer, char line[100], for both calls to fgets(). Strtok returns a pointer to a character in the line buffer, so when you store in "line" the female names, all these pointers, relative to line when line contained the male names, are now invalid. Try storing the female line in other buffer, it should work.

EDIT: Sorry if the "not paying attention..." sounds discouraing. Nothing more far away from my intention. Everyone make mistakes everytime, specially when learning. I wish you good luck with the process :)

够钟 2024-10-01 23:43:17

正如@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;
}

As @lacqui already mentioned, you had potential buffer overruns. I changed the fgets to pass sizeof(line1)-1 instead of a hard coded value. That way the compiler will figure how what size to pass...even if you later decide to increase / decrease the buffer size. The minus 1 is so fgets will not overwrite the null terminator at the end. I also initialize the buffers using memset.

I also added another line buffer because strtok modifies the string by replacing the specified delimiter chars with null and returning a pointer to a token position in that string...strtok does not make copies.

I changed the delimiters to include \r and \n in addition to spaces.

#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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文