Std :: string由返回char *的函数赋值

时间:2012-04-11 18:37:11

标签: c++

更新:对于getValue函数,我无法控制,所以我可以从我这边做什么?

我对string和char * basic有一个愚蠢的问题。

我正在使用一个返回char *值的函数,

const char *getValue(const char *key)
{
    //if key found, and valueString is a string
      return valueString.c_str();
    //else
      return NULL;
}

然后我初始化一个字符串来保存返回值

std::string value = getValue(key);

问题是,每当找不到值时,这意味着函数返回NULL,我的赋值行将遇到异常。但是当有合法的回报价值时,一切都运转良好。

我在想 这种用法完全错了吗?意味着我永远不应该将char *与字符串混合? 2.如果没有,那么当有一个合法的指针返回时,我的字符串会自动复制并存储吗? 3.最好的方法是什么?

感谢。

6 个答案:

答案 0 :(得分:5)

首先,如果valueString是该函数的本地函数,则使用返回的指针将给出未定义的行为。

其次,返回空指针是否合理将取决于您如何使用该指针,而您没有告诉我们任何内容。

除非你绝对,否则必须摆弄指针,只需返回一个字符串,让你的生活变得更加轻松。

答案 1 :(得分:4)

通过返回NULL报告错误发生(如果找不到 键)并不是一个好主意。在这种情况下,您应该在函数内生成有意义的异常。类似于NotFoundEx

如果您无法控制该功能,则应将其包装到您的安全代码中:

const char* getSafeValue(const char *key)
{
  const char* value = getValue(key);
  if(value == NULL)
    throw NotFoundEx();

  return value;
}


std::string value = getSafeValue(key);

答案 2 :(得分:3)

由于您无法控制getValue()函数的作用,因此需要先检查NULL的返回值,然后再将其赋值给std::string

std::string value;  // value is an empty string
const char *retVal = NULL;

if( ( retVal = getValue(key) ) != NULL ) {
  value.assign( retVal );
}

答案 3 :(得分:0)

由于您正在使用std::string值,我只会返回std::string而不是char*

std::string getValue(const char *key) 
{ 
    if (key found)
        return valueString; 
    else 
        return std::string(); 
} 

答案 4 :(得分:0)

您希望std::string具有超出范围的值。 (char *)可能不是理想的方法(请参阅boost::optional以获得更好的方法),但它会起作用(假设您没有使用堆栈局部变量) - if < / em>你检查出界值。也就是说,这里的问题并不是真正混合(char *)std::string,而是你没有检查“未找到”,而是盲目地假设在这种情况下会发生一些明智的事情。

不要假设;确定如果找不到密钥需要执行的操作,并检查NULL(或其他带外情况,如果您选择使用其他密码)。

答案 5 :(得分:0)

第一个问题:数据来自哪里?你无法归还 c_str()对局部变量的结果;这是未定义的行为,而且 你刚才运气好不好。如果是valueString 只是一些更持久的数据的副本,然后你可以调用c_str 直接在它上面。然而,更一般地说,无论你返回什么,你都会 在尝试使用它之前必须验证它是否有效。最简单的 解决方案(但并非总是可行)只是使用一个sentinal值 string,例如:

std::string
getValue( std::string const& key )
{
    //  ...
    return condition ? valueString : std:;string();
}

例如,使用空字符串作为sentinal。

如果函数的语义不提供方便的sentinal value - 例如,如果函数可以返回一个空字符串作为 有效价值 - 然后你将不得不做其他事情。

如果返回值是某个long中的查找结果 live container,然后你可以返回一个指向元素的指针 在容器中。然而,一般而言,指针构成了问题 他们指的是什么;如果你没有生命的东西 足够了,那么你不想使用指针。

另一种可能性是呼叫者提供默认值:

std::string
getValue( std::string const& key, std::string const& ifNotFound )
{
    // ...
    return condition ? valueString : ifNotFound;
}

这将把定义的遗嘱的责任转移到了 被叫方。在像字符串这样的情况下,几乎总有一些价值 被叫者无法做任何事情,因此可以用作哨兵。

最常见的替代方案是某种FallibleMaybe class:一个组合状态的类对象(通常只有一个bool) 和实际数据类型的实例。数据是有效还是有效 不取决于状态的值,所以你仍然需要检查:

Fallible<std::string>
getValue( std::string const& key )
{
    //  ...
    return condition
        ? Fallible<std::string>( valueString )
        : Fallible<std::string>();
}

这在内部通常也很有效:

Fallible<std::string>
getValue( std::string const& key )
{
    Fallible<std::string> results;
    //  ...
    // At some point, I've got a valid return value, so I do:
        results.validate( valueString );
    // in a condition, of course...
    return results;
}

(只是一个频繁和方便的模式的例子。)