C - 截断char *字符串参数

时间:2017-03-06 08:35:31

标签: c linux

我一直在努力做这个简单的任务一段时间,但由于我不熟悉纯C技巧,所以无法正常工作。

基本上我有一个函数可以被我自己编写的代码块调用,无法编辑。

int myMethod(char* str);

我的任务是找到char *中子字符串的位置,如果找到,则从索引0获取字符串到找到的子字符串的索引,并将其分配给原始的char * str。

这是我尝试做的事情:

int myMethod(char* str)
{    
    int splitPos = strstr(str, "Pikachu") - str;
    char buffer[splitPos + 1];
    strncpy(buffer, str, splitPos);

    buffer[splitPos] = '\0';
    memcpy(str, buffer, strlen(buffer) + 1);
}

我在最后一次strcpy通话中得到了一个SegFault。我尝试用相同的结果将其更改为以下内容

  • memmove(str,buffer,...)
  • 的strcpy(...)

1 个答案:

答案 0 :(得分:4)

您的功能存在多个问题:

  • 您没有检查strstr的返回值是否成功。如果代码无法找到子字符串,则代码具有未定义的行为。
  • 如果源长度超过strncpy
  • splitPos-1将不会终止目标字符串。不要使用strncpy,它不会按照您的想法执行,对程序员和读者来说都非常容易出错。出于您的目的,memcpy具有相同的参数是等效的,并且问题较少。
  • strlen(buffer)是多余的,评估为splitPos
  • 您实际上不需要为您的目标设置临时缓冲区:只需将子字符串的开头设置为'\0'即可截断字符串。
  • 如果目标字符串是只读的,则修改它具有未定义的行为,并可能解释观察到的分段错误。

这是一个简化版本:

int myMethod(char *str) {    
    char *p = strstr(str, "Pikachu");
    if (p != NULL) {
        *p = '\0';
    }
}

相反,如果您只需要在myMethod中的更多代码中操作子字符串,您可以制作副本以避免尝试修改原始字符串:

int myMethod(char *str) {    
    char *p = strstr(str, "Pikachu");
    size_t len = p ? p - str : stren(str);
    char buffer[len + 1];
    memcpy(buffer, str, len);
    buffer[len] = '\0';
    str = buffer;
    /* use `str` in this function */
}