`std :: string :: substr`返回无效指针?

时间:2014-10-20 01:21:09

标签: c++ string pointers substring c++-standard-library

我正在编写一个函数,根据特定字符的位置将C ++ string拆分为两个单独的string。但是,当我使用它返回的指针时,它们似乎无效。这是一个例子:

#include <iostream>
#include <string>

bool SplitString(std::string &input, char splitChar, std::string **left, std::string **right)
{
    std::string::size_type offset = input.find(splitChar);
    if (offset == std::string::npos) return false;
    *left = &input.substr(0, offset);
    *right = &input.substr(offset + 1);
    return true;
}

int main(int argc, char *argv[])
{
    std::string input = "Left side:Right side";
    std::string *left;
    std::string *right;

    if (SplitString(input, ':', &left, &right)) {
        std::cout << "left = \"" << *left << "\"" << std::endl;
        std::cout << "right = \"" << *right << "\"" << std::endl;
    } else {
        std::cout << "Didn't find ':' - this shouldn't happen!" << std::endl;
    }

    return 0;
}

这应该输出以下内容:

left = "Left side"
right = "Right side"

为什么它不起作用?

2 个答案:

答案 0 :(得分:3)

这里你不需要指针。您可以参考leftright。可以说,你不需要通过引用取input(你不修改它,如果你这样做,如果你必须对同一个输入执行其他操作会怎么样?)所以要么按值传递它(如果您打算处理副本)或const&(表示不修改它的意图)。

bool SplitString(std::string input, char splitChar, std::string& left, std::string& right)
{
    std::string::size_type offset = input.find(splitChar);
    if (offset == std::string::npos) return false;
    left = input.substr(0, offset);
    right = input.substr(offset + 1);
    return true;
}

// ...

    std::string left;
    std::string right;

    if (SplitString(input, ':', left, right)) {

// ...

答案 1 :(得分:-6)

当我用g++编译我的测试代码时,它给了我一个警告,即Visual C ++编译器没有给我。问题是std::string::substr返回的对象被认为是“临时的”,并且在函数外部使用时无效。解决方案是使用*left = &input.substr(0, offset),而不是*left = new std::string(input.substr(0, offset))。显然,以类似的方式修改*right行。

完成后,不要忘记delete新对象!

这是工作代码:

#include <iostream>
#include <string>

bool SplitString(std::string &input, char splitChar, std::string **left, std::string **right)
{
    std::string::size_type offset = input.find(splitChar);
    if (offset == std::string::npos) return false;
    *left = new std::string(input.substr(0, offset));
    *right = new std::string(input.substr(offset + 1));
    return true;
}

int main(int argc, char *argv[])
{
    std::string input = "Left side:Right side";
    std::string *left;
    std::string *right;

    if (SplitString(input, ':', &left, &right)) {
        std::cout << "left = \"" << *left << "\"" << std::endl;
        std::cout << "right = \"" << *right << "\"" << std::endl;
    } else {
        std::cout << "Didn't find ':' - this shouldn't happen!" << std::endl;
    }

    delete left;
    delete right;
    return 0;
}