此子字符串函数有什么问题

时间:2019-09-02 04:21:40

标签: c++ string

当我尝试将其输出时,子字符串未输出任何内容。我应该得到一些输出

请参见下面的代码,但基本上我将2个参数分别设置为a和b,其中a是起始位置,b是要复制的字符数。但功能跳到最后

   DSString DSString :: substring(int a, int b){
        if(a >= 0 && b > a){
            char* tmp = new char[b - a + 1];
            strncpy(tmp,data,b-a);
            DSString result(tmp);
            delete [] tmp;
            return result;
        }
       return DSString("");
    }

对于“ Hello”,参数3和2预期显示为“ lo”,但返回的是空字符串。

2 个答案:

答案 0 :(得分:1)

请注意以下几点:

  • 您必须使用a两次-计算复制的字符数(我看到了)并找到子字符串的开头(我希望像data + a这样的东西)
  • 因为“如果源大于num,则在目标末尾没有隐含的空字符。”(see C++ references),您必须向{{1 }}。复制数据后。
  • tmp的数据类型必须为data(实际上我看不到定义)
  • 应该在构造器char *中为char * data分配内存(问题中也未显示)

答案 1 :(得分:0)

实现输入参数的方式,a是起始索引,b是结束索引。但是,您无法验证任何一个索引是否超出要从其复制的data缓冲区的范围。实际上,从data缓冲区进行复制时,您甚至根本没有使用起始索引。

此外,尽管您正在分配tmp缓冲区以包含用于空终止符的空间,但是您并没有告诉strncpy()有空终止符的空间,因此它不会输出空终止符。 ,并且您没有提供自己的空终止符。

尝试以下方法:

DSString DSString::substring(int start, int end)
{
    if (start >= 0 && start < end)
    {
        int len = strlen(data);
        if (end > len) end = len;
        int count = end - start;
        if (count > 0)
        {
            char* tmp = new char[count + 1];
            memcpy(tmp, data + start, count);
            tmp[count] = '\0';
            DSString result(tmp);
            delete [] tmp;
            /* alternatively:
            DSString result;
            result.data = tmp;
            */
            return result;
        }
    }
    return DSString("");
}

但是,鉴于您提供的示例,您实际上期望第二个参数是一个计数,而不是一个索引,因此请尝试以下操作:

DSString DSString::substring(int start, int count)
{
    if (start >= 0 && count > 0)
    {
        int len = strlen(data);
        if ((start + count) > len)
            count = len - start;
        if (count > 0)
        {
            char* tmp = new char[count + 1];
            memcpy(tmp, data + start, count);
            tmp[count] = '\0';
            DSString result(tmp);
            delete [] tmp;
            /* alternatively:
            DSString result;
            result.data = tmp;
            */
            return result;
        }
    }
    return DSString("");
}

话虽如此,您可以通过添加一个以tmp和长度作为输入的构造函数来完全避免使用char*缓冲区:

DSString::DSString(char *d, int count)
{
    if (d && count > 0)
    {
        data = new char[count + 1];
        memcpy(data, d, count);
        data[count] = '\0';
    }
    else
        data =  nullptr;
}

然后您可以根据需要执行以下一项操作:

DSString DSString::substring(int start, int end)
{
    if (start >= 0 && start < end)
    {
        int len = strlen(data);
        if (end > len) end = len;
        return DSString(data + start, end - start);
    }
    return DSString("");
}
DSString DSString::substring(int start, int count)
{
    if (start >= 0 && count > 0)
    {
        int len = strlen(data);
        if ((start + count) > len)
            count = len - start;
        return DSString(data + start, count);
    }
    return DSString("");
}