【问题标题】:Using strtok and trying to store their values into an array使用 strtok 并尝试将它们的值存储到数组中
【发布时间】:2020-05-01 15:51:12
【问题描述】:

我对 C 很陌生,我一直在尝试一些东西,但它似乎并没有真正奏效: 我有一个数组char *initialParts;,我根据用户的输入分配空间,但我认为这并不重要。 我还有一个计数器initialPartsCounter = 0; 用作索引,以便在分配的内存的每个索引处存储一个字母。 到目前为止,我得到了这个:

            char *initialParts;
            const char comma[3] = ",";
            int initialPartsCounter = 0;
            initialParts = (char*)malloc((int)numInitialParts * sizeof(char));
            char *token;
            token = strtok(fileLine, comma);

            while (token != NULL) {
                strcpy(&initialParts[initialPartsCounter], token);
                initialPartsCounter++;
                token = strtok(NULL, comma);
            }

            for (int l = 0 ; l < (int)numInitialParts; l++)
            {
                printf("%c", initialParts[l]);
            }

其中 numInitialParts 是用户输入的数字,fileLine 是文件中读取的行。 在以下示例中,numInitialParts = 4and fileLine = 'q,d,c,k' 在我的 for 循环中,打印的输出很奇怪:qdck☐☐☐☐(我无法复制 k 之后的字符,因为我粘贴它时它没有做任何事情,但它类似,请查看图片以查看它的外观)。

编辑:我理想的输出是:

qdck

如果有人有解决此问题的想法,我会很高兴听到它。谢谢!

【问题讨论】:

  • "打印的输出很奇怪" 你希望得到哪个输出?
  • initialPartschar* 吗?请发布一个完整的示例。另外:filename 是如何定义的?
  • 您读取了initialPartsCounter 标记,但打印了numInitialParts 字符。
  • "将它们的值存储到一个数组中" 字符串还是字符?看起来您正在尝试从输入字符串中删除分隔符。请在您的帖子中添加两件事:(a)示例字符串和(b)您希望输出的样子。这就是为什么最好先编写测试。
  • 如果 fileLine 是 x,k,c,d,,xk,xkc,xkcd,你希望控制台显示什么。这样的例子会暴露更多的边缘。

标签: c arrays strtok


【解决方案1】:

因为你打印

printf("%c", initialParts[l]);

我可以猜到initialParts被定义为char *,然后动态分配。

strtok 通常用于获取各种长度的令牌。即使您可能确定原来的逗号分隔字符串仅由一个字符组成,但当您执行时

strcpy(&initialParts[initialPartsCounter], token);

您正在将至少两个字符复制到 char 数组:令牌的字符(例如 'q')和字符串终止符 '\0'(字符串只是一个以零结尾的字符数组,所有的字符串操作函数都依赖它)。

做事

initialParts[initialPartsCounter] = *token;

确实,这不是主要错误。事实上,即使它对strtok 的工作方式存在一些误解,但它会一直工作,直到initialParts 数组中有足够的空间来存储当前字符和字符串终止符。

另一个错误是,虽然你从 strtok 解析中只得到 initialPartsCounter 字符,但你打印了数组的所有字符 (numInitialParts)。最后的那些将毫无意义,因此更正它的代码将按预期工作。

以下示例将您的代码嵌入到一个简单的 main 函数中(我手动定义了输入 `char fileLine[] = "q,d,c,k"):

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

int main(void)
{
  char *initialParts, *token;
  char fileLine[] = "q,d,c,k";
  const char comma[3] = ",";
  int initialPartsCounter = 0, numInitialParts = 20;
  initialParts = (char*)malloc((int)numInitialParts * sizeof(char));

  token = strtok(fileLine, comma);

  while (token != NULL)
  {
    //strcpy(&initialParts[initialPartsCounter], token);
    initialParts[initialPartsCounter] = *token; //Use this only if tokens are only one char long
    initialPartsCounter++;
    token = strtok(NULL, comma);
  }

  for (int l = 0 ; l < initialPartsCounter; l++)
  {
    printf("%c", initialParts[l]);
  }
  printf("*end\n");

  free(initialParts);

  return 0;
}

我还打印了一个 结束字符串 以显示没有任何尾随的意外字符。输出是

qdck*end

【讨论】:

  • 您的解决方案不起作用,我仍然得到相同的输出。
  • 您是否也将 for 循环从 for (int l = 0 ; l &lt; (int)numInitialParts; l++) 更改为 for (int l = 0 ; l &lt; (int)InitialPartsCounter; l++)
  • @MM1。我是。稍后我会整理出来
  • @MM1 我试过了,我确认它有效。如果在您的完整实现中它不起作用,则可能意味着您附加的代码不完整。我将使用一个完整的主应用程序来编辑我的答案,以展示其行为。
【解决方案2】:
initialParts = (char*)malloc((int)numInitialParts * sizeof(char));

您应该使用双指针或二维数组来存储token(因为它是字符序列(字符串)而不是字符)。如果之前不知道有多少个部分,可以在每次增加numInitialParts时使用realloc

例如:

char **initialParts = malloc(sizeof(char*));

// check initialParts here

token = strtok(fileLine, comma);

while (token != NULL) {
    initialParts[initialPartsCounter] = malloc(sizeof(char) * 2);
    // check initialParts[initialPartsCounter] here
    strcpy(initialParts[initialPartsCounter], token);
    initialPartsCounter++;
    initialParts = realloc((initialPartsCounter+1)*sizeof(char));
    // check initialParts here
    token = strtok(NULL, comma);
 }

【讨论】:

    猜你喜欢
    • 2016-03-31
    • 2022-11-17
    • 2015-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-05
    • 1970-01-01
    • 2014-08-14
    相关资源
    最近更新 更多