【问题标题】:strtok seems to delete string portion - Am I using it right?strtok 似乎删除了字符串部分 - 我用对了吗?
【发布时间】:2016-11-19 17:30:23
【问题描述】:

我想使用 strtok() 将一行划分为标记,但该函数似乎只是生成第一个标记并“破坏”其余标记。我使用 printf() 检查发生这种情况的位置,发现就在token= strtok(line,delimit) 之后。 这是我的 main、read_line 和 parse_args 函数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define PROMPT "$"
#define MAX_LINE 512
void main(){
    char line[MAX_LINE]; 
    while(read_line(line)){
        execute_line(line);
    }
}

char *read_line(char *line){ 
    printf("%s ",PROMPT);
    fflush(stdout);
    line=fgets(line,MAX_LINE,stdin);
    return line;
}

int parse_args(char **args, char *line){
    printf("%s", line); //If it reads "Hello how are you?", here it prints properly
    int n=0;
    char* token;
    char delimit[]=" \t\r\n\v\f";
    token=strtok(line,delimit);
    printf("%s", line); //however here it just prints "Hello" 
    while(token!=NULL){
        printf("token%i: %s\n",n,token);
        *args=token;
        n++;
        *args++;
        token=strtok(NULL,delimit);
    }
    printf("token%i: %s\n",n,token);
    *args=token;
    return n;
}

int execute_line(char *line){
    char **args;
    parse_args(args,line);
    check_internal(args);
    return 0;
}

【问题讨论】:

  • void main 错误; main 应该返回 int
  • 你错过了几个#includes。
  • MAX_LINE 未定义。
  • 见:en.cppreference.com/w/c/string/byte/strtok。特别是#1 的第 6 个项目符号。
  • 你永远不会打电话给parse_args

标签: c string pointers strtok


【解决方案1】:

strtok 将分隔符替换为 NUL 字符,以便它可以返回指向仍在原始缓冲区中的标记的指针。

*args++ 具有误导性。它确实增加了args,但* 是不必要的。

【讨论】:

  • 哦,是的。 * 是不必要的。
  • @KeineLust parse_args() 从未在 OP 代码中调用。 很可能,OP 只是未能发布完整的 MCVE。
  • 感谢@pat,原来是 *,但是现在它报告了分段错误...
  • 现在我可以看到execute_line,我可以看到您没有为args 数组分配任何内存。您应该在execute_line 中将args 声明为char *args[MAX_ARGS+1](并为MAX_ARGS 选择一些值;+1 是您最后存储的NULL)。请注意,在当前代码中,如果 args 过多,则会导致数组溢出;您应该执行边界检查。
  • 哦,将delimit 声明为数组将导致函数在每次调用parse_args 时将字符串复制到堆栈中。最好将delimit 声明为const char *delimit = "...",这样您就可以在常量字符串部分使用副本。
【解决方案2】:

the standard declaration:

#include <string.h>

char *strtok(char *restrict s, const char *restrict sep);

注意好吧char *restrict s 不包含conststrtok() 修改它正在拆分为标记的字符串。

【讨论】:

    【解决方案3】:
    token=strtok(line,delimit);
    printf("%s", line); //however here it just prints "Hello"
    

    这正是 strtok 所做的 :)

    它实际上占用了您的行,并放置了一个 '\0' 而不是下一个分隔符。 您应该尝试使用调试器查看您的代码,之后使用 strtok 会更有意义。

    祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-08
      • 2022-01-04
      • 2010-12-01
      相关资源
      最近更新 更多