C++-将null赋值给std::字符串
C++ - Assigning null to a std::string
我正在自学C++。我有以下代码,但它给出了错误。
#include <iostream>
#include <string>
using namespace std;
int setvalue(const char * value)
{
string mValue;
if(value!=0)
{
mValue=value;
}
else
{
mValue=0;
}
}
int main ()
{
const char* value = 0;
setvalue(value);
cin.get();
return 0;
}
因此,我想创建一个接受char指针的函数,并将指针传递给它。该函数将指针分配给它的成员变量。我故意传递一个空指针。以下是我得到的错误:
D:CPPTestCP.cpp In function `int setvalue(const char*)':
note C:Dev-Cppincludec++3.4.2bitsbasic_string.h:422 candidates are: std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
note C:Dev-Cppincludec++3.4.2bitsbasic_string.h:422 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(const _CharT*) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
note C:Dev-Cppincludec++3.4.2bitsbasic_string.h:422 std::basic_string<_CharT, _Traits, _Alloc>& std::basic_string<_CharT, _Traits, _Alloc>::operator=(_CharT) [with _CharT = char, _Traits = std::char_traits<char>, _Alloc = std::allocator<char>]
它基本上是在抱怨行:mValue=0;
它为什么抱怨这条线?我不能为字符串分配null?
我不能为字符串分配null?
没有。std::string
不是指针类型;它不能被设为"null"。它不能表示没有值,而null指针就是用来表示的。
通过为其分配一个空字符串(s = ""
或s = std::string()
)或清除它(s.clear()
),可以使为空。
不能将NULL
或0
分配给C++std::string
对象,因为该对象不是指针。这是与C风格字符串的一个关键区别;C样式字符串可以是NULL
或有效字符串,而C++std::string
总是存储一些值。
没有简单的解决办法。如果你想保留一个sentinel值(比如,空字符串),那么你可以做一些类似的事情
const std::string NOT_A_STRING = "";
mValue = NOT_A_STRING;
或者,您可以存储一个指向字符串的指针,以便将其设置为null:
std::string* mValue = NULL;
if (value) {
mValue = new std::string(value);
}
希望这能有所帮助!
文字0
的类型为int
,不能将int
分配给std::string
。使用mValue.clear()
或指定一个空字符串mValue=""
。
有两种方法可以考虑,它们在处理C风格字符串的空指针时可以达到相同的效果。
三元算子
void setvalue(const char *value)
{
std::string mValue = value ? value : "";
}
或者谦逊的if语句
void setvalue(const char *value)
{
std::string mValue;
if(value) mValue = value;
}
在这两种情况下,只有当value
是而不是空指针时,value
才被分配给mValue
。在所有其他情况下(即,当value
为null时),mValue
将包含一个空字符串。
三元运算符方法可能有助于在value
:中没有值的情况下提供替代默认字符串文字
std::string mValue = value ? value : "(NULL)";
我不会争辩说这是一个好的想法(或使用nullptr
与非指针的事物的语义),但创建一个提供"可为null"语义的类相对简单(请参阅nullable_string)。
然而,这更适合C++17的std::optional:
#include <string>
#include <iostream>
#include <optional>
// optional can be used as the return type of a factory that may fail
std::optional<std::string> create(bool b)
{
if (b)
return "Godzilla";
else
return {};
}
int main()
{
std::cout << "create(false) returned "
<< create(false).value_or("empty") << std::endl;
// optional-returning factory functions are usable as conditions of while and if
if (auto str = create(true))
{
std::cout << "create(true) returned " << *str << std::endl;
}
}
如示例中所示,std::optional
可以转换为bool
,或者您可以使用has_value()
方法,对坏访问有例外,等等。这为您提供了可为null的语义,这似乎是Maria试图实现的。
如果你不想等待C++17的兼容性,请参阅关于Boost.Optional.的答案
else
的情况是不必要的,当您创建string
对象时,默认情况下它是空的。
编译器给出错误,因为当为mValue=0编译器赋值时,会为编译时绑定找到赋值运算符=(int),但它不存在于字符串类中。如果我们将下面的语句强制转换为类似mValue=(char)0的char,那么它的编译成功了,因为字符串类包含运算符=(char)方法。
许多C API使用空指针来指示"使用默认值",例如mosquitopp。以下是我使用的模式,基于David Cormack的回答:
mosqpp::tls_set(
MqttOptions->CAFile.length() > 0 ? MqttOptions->CAFile.c_str() : NULL,
MqttOptions->CAPath.length() > 0 ? MqttOptions->CAPath.c_str() : NULL,
MqttOptions->CertFile.length() > 0 ? MqttOptions->CertFile.c_str() : NULL,
MqttOptions->KeyFile.length() > 0 ? MqttOptions->KeyFile.c_str() : NULL
);
它有点麻烦,但允许将所有内容都作为std::string
保留到API调用本身。
- 我可以重新分配/覆盖std::字符串吗
- 如何将这个std::字符串转换为std::基本字符串
- std::字符串与 PCWSTR 的对话
- 重载 std::字符串运算符+ 用于打印枚举名称
- 从std::字符串创建OssBitString
- std::字符串擦除以删除最后一个字母
- 如何使用 C++ 中的原语初始化类(如 std::字符串从 const char* 初始化)
- std::字符串串联操作
- 如何有效地将一个大std::字符串的一部分转换为float
- 转义std::字符串中的特殊字符
- 用C++替换std::字符串中的一个子字符串,但不能全部替换
- C++std::字符串流到常量字符*的转换
- 如何将std::字符串转换为不同的字符串类
- 对齐C++字符串类型问题 std::字符串到 TStr
- std::字符串到字符*而不切割字节
- 编写具有非ASCII数据的std ::字符串
- 将 Delphi 的字符串转换为 std::字符串用于C++
- std::字符串添加到字符*
- 字符* 和 std::字符串和常量字符*之间的转换
- 用指针访问std ::字符串中的元素