【问题标题】:C: STRTOK exception [duplicate]C:STRTOK异常[重复]
【发布时间】:2014-01-15 18:38:00
【问题描述】:

由于某种原因,我在第一次使用 strtok() 时遇到异常 我想要完成的是一个简单地检查子字符串是否在字符串中重复的函数。但到目前为止我还没有让 strtok 工作

int CheckDoubleInput(char* input){
char* word = NULL;
char cutBy[] = ",_";

word = strtok(input, cutBy);  <--- **error line**

/* walk through other tokens */
while (word != NULL)
{
    printf(" %s\n", word);
    word = strtok(NULL, cutBy);
}
return 1;
}

和主要调用函数:

CheckDoubleInput("asdlakm,_asdasd,_sdasd,asdas_sas");

【问题讨论】:

标签: c string strtok


【解决方案1】:

CheckDoubleInput() 没问题。看这个。希望你能理解

int main(){
    char a[100] = "asdlakm,_asdasd,_sdasd,asdas_sas";
    // This will lead to segmentation fault.
    CheckDoubleInput("asdlakm,_asdasd,_sdasd,asdas_sas");
    // This works ok.
    CheckDoubleInput(a);
    return 0;
}

【讨论】:

  • 不,这令人困惑// This will lead to segmentation fault 为什么?我想解释一下..
  • @Grijesh Chauhan:因为它是一个指向常量的指针。 strtok() 修改第一个参数。
  • 哦,所以您的意思是您的评论是针对第二行而不是针对第二行...明白了。
【解决方案2】:

strtok 函数修改其第一个输入(已解析的字符串),因此您不能将指针传递给常量字符串。在您的代码中,您将指针传递给char[N] 类型的字符串文字(即编译常量字符串),因此尝试修改未定义行为的常量字符串文字。您必须先将字符串复制到临时缓冲区中。

char* copy = strdup("asdlakm,_asdasd,_sdasd,asdas_sas");
int result = CheckDoubleInput(copy);
free(copy);

man page for strtok 是这样说的:

错误

使用这些功能时要小心。如果您确实使用它们,请注意:

  • 这些函数修改了它们的第一个参数。
  • 这些函数不能用于常量字符串。
  • 定界字节的标识丢失。
  • strtok() 函数在解析时使用静态缓冲区,因此它不是线程安全的。如果这对您很重要,请使用 strtok_r()

【讨论】:

  • 谢谢,但我不能像那样初始化 char* copy = strcpy("asdlakm,_asdasd,_sdasd,asdas_sas");,我需要它来获取 *char 作为参数发送
  • @FelixKreuk 实际上应该是strdup() 更新的答案。再读一遍
【解决方案3】:

input 中的任何一个都不好。尝试在调用 strtok 之前打印它,或者您在带有 GCC 编译器的多个线程上使用 strtok。一些编译器有一个称为“strtok_r”的线程安全版本。 Visual Studio 已将原始函数修复为线程安全的。

您修改后的答案表明您正在传递一个只读字符串。

【讨论】:

  • 我附上的图片可以看到input的值是ok的
  • 不行,传递字符串字面量是危险的。传递它的副本,因为 strtok 将修改它。存储字符串文字的内存是只读的。
猜你喜欢
  • 1970-01-01
  • 2018-08-12
  • 2014-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多