【问题标题】:Only getting 2 tokens per line from strtok()每行仅从 strtok() 获得 2 个标记
【发布时间】:2016-07-17 20:36:55
【问题描述】:

我正在尝试从输入文件中制作令牌。因此,我得到一行 fgets 并将其提供给一个辅助方法,该方法接受一个 char* 并返回一个 char* 令牌。我正在使用带有分隔符的 strtok() 作为“”,因为标记都由“”分隔。但是,我无法弄清楚为什么代码每行只生成 2 个标记,并且只是移动到下一行,即使该行中还有更多需要标记。代码如下:

char *TKGetNextToken( char * start ) {
    /* fill in your code here */
    printf("Entered TKGetNextToken \n");
    printf(&start[0]);
    char* temp = &start[0];

    //Delimiters for the tokens
    const char* delim = " ";

    //store tempToken
    char* tempTok = strtok(temp, delim);

    //return the token
    return tempTok;
}

这是我在 main 方法中存储令牌的方式:

//call get next token and get the token and store into temptok
    while (temp!= NULL) {
        tempTok = TKGetNextToken(temp);
        printf("tempTok: %s\n",tempTok);
        token.charPtr[tempNum] = tempTok;
        tempNum++;
        printf("Temp:  %s\n",tempTok);
        temp = strtok(NULL, " \0\n");
    }

所以,假设我有一个 file.txt:

abcd ef ghij asf32
fsadf ads adf

创建的标记将是“abcd”和“ef”,它将继续下一行而不为“ghij”和“asf32”创建标记。

【问题讨论】:

  • 注意:C不支持方法,只支持函数
  • printf(&start[0]); 显然是不行的! 从不将 usafe 数据作为格式字符串传递!这是最典型的恶意软件入口点之一(也是最容易避免的)。
  • 你在函数和调用者的同一个字符串上调用strtok。嗯,有点。它实际上是对同一字符串的 NULL 和非 NULL strtok 调用的混合。更糟糕的是。这几乎肯定不是你想要的。要更详细地了解正在发生的事情,建议您使用调试器。
  • 您已接近minimal, complete, and verifiable example (MCVE),但您缺少main 中的一些重要代码。发布 MCVE 使问题更容易回答。也就是说,答案将是完全删除 TKGetNextToken 函数,因此您需要解释为什么该函数存在,以及它为什么有用。

标签: c


【解决方案1】:

strtok使用正确的语法

        char *tempTok = strtok(line, " "); //initialize
        while (tempTok != NULL) {
            //do the work
            tempTok = strtok(NULL, " \n"); //update
        }

如果你喜欢上面的方法,那么你可以很容易地获得令牌。请看一下这个例子,它和你的代码类似,只要记住你如何正确使用strtok,它就会起作用。查看strtok 以及它如何在循环中使用、更新和使用char *

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

int main() {
    FILE *fp = fopen("data.txt", "r");
    char line[256];
    while (fgets(line, sizeof(line), fp)) {
        char *tempTok = strtok(line, " ");
        while (tempTok != NULL) {
            printf("token %s\n", tempTok);
            tempTok = strtok(NULL, " \n");
        }
    }
    fclose(fp);
    return 0; 
}

文件数据.txt

abcd ef ghij asf32
fsadf ads adf

输出

./a.out 
token abcd
token ef
token ghij
token asf32

token fsadf
token ads
token adf

【讨论】:

  • 我还会从分隔符列表中删除\0。有两个原因。 (1) strtok 无论如何都会停在\0,因为那是字符串的结尾。 (2) 当您在分隔符中放置\0 时,之后的所有内容都将被忽略,因为\0 终止了分隔符列表。这就是为什么asf32 后面有一个空行:分隔符中的\n 被忽略了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-08-12
  • 1970-01-01
  • 2016-07-05
  • 2018-07-26
  • 2021-10-20
相关资源
最近更新 更多