【问题标题】:strtok causing segfault but not when step through codestrtok 导致段错误,但不是在单步执行代码时
【发布时间】:2013-07-09 15:03:56
【问题描述】:

我是 C 新手,我正在尝试将日期/时间字符串拆分为单独的变量。但是,当我逐行遍历 gdb 中的代码时,它可以工作,但是,当我让它正常运行而没有断点时,它会出现段错误,我不明白为什么。

下面是代码:

char * dateTimeString = "2011/04/16 00:00";
char dateVar[11];
char timeVar[6];

if (splitTimeAndDateString(dateVar, timeVar, dateTimeString))
{
    exit(1);
}

printf("Date: %s\tTime: %s\n", dateVar, timeVar);

下面是函数

int splitTimeAndDateString(char date[11], char time[6], char * dateString)
{
    char *token;
    token = strtok(dateString, " ");
    int i = 0;
    while (token != NULL)
    {
        if (i == 0)
        {
            strcpy(date, token);
        }
        else if (i == 1)
        {
            strcpy(time, token);
        }
        else
        {
            printf("Overrun date time string\n");
            return 1;
        }
        token = strtok(NULL, " ");
        i++;
    }
    return 0;
}

感谢您提供的任何帮助。

【问题讨论】:

标签: c strtok


【解决方案1】:

strtok() 函数修改要解析的字符串,并将所有分隔符替换为\0 nul 符号。

阅读:char * strtok ( char * str, const char * delimiters );

str
C 字符串要截断。
注意这个字符串的内容 被修改并分解成更小的字符串(令牌)。或者, 可以指定空指针,在这种情况下函数继续 扫描上一次成功调用函数的位置。

在您的代码中:

 strtok(dateString, " "); 
           ^
           |  is a constant string literal 

dateString 指向"2011/04/16 00:00" 一个常量字符串文字,并且通过使用strtok() 您的代码试图在只读内存上写入 - 这是非法的,这会导致分段错误。

阅读此linked answer for diagram 以了解:strtok() 是如何工作的?

编辑:

@: char * strtok ( char * str, const char * delimiters ); 在给定的代码示例中,str 是一个数组,而不是常量字符串文字。其声明:

char str[] ="- This, a sample string.";

这里str[] 是一个以空字符结尾的字符数组,它用字符串初始化,其长度等于分配字符串的大小。您可以更改str[] 的内容,例如str[i] = 'A' 是一个有效的操作。

而在您的代码中:

char * dateTimeString = "2011/04/16 00:00"; 

dateTimeString 是指向不可修改的字符串字面量的指针,例如 dateTimeString[i] = 'A' 这次是非法操作。

【讨论】:

  • 我不是你的意思,我举了cplusplus.com/reference/cstring/strtok的例子。我在第一次调用时在 strToke 中使用 dateString,然后在 while 循环中的第二次调用中使用 strtok(NULL, " ")
  • @Boardy 这里 char str[] ="- This, a sample string."; 是数组而不是 const 字符串
  • @Boardy yes strtok 尝试将dataString 划分为标记,而它是不可修改的常量字符串文字。而且str[]*str是有区别的。
  • 我不知道这个:-) 谢谢。从手册页中,我们有“令牌的此结尾自动替换为空字符,并且该令牌的开头由函数返回.....找到最后一个令牌的点由内部保存下次调用时要使用的函数(不需要特定的库实现来避免数据竞争)。”。
  • @GrijeshChauhan,是的,它现在正在工作,不知道发生了什么,大约 5 分钟后,我中止服务器锁定并需要重新启动,现在它正在工作。这有点过时了,不可靠,因此服务器出现了一些奇怪的问题。谢谢你的帮助。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2014-12-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多