连接常量字符 * 字符串
concatenate const char * strings
我对char *
和const char *
感到困惑。在我的示例中,我不确定如何将它们放在一起。我有几个const char *
字符串,我想连接到最后一个const char *
字符串。
struct MyException : public std::exception
{
const char *source;
int number;
const char *cause;
MyException(const char *s, int n)
: source(s), number(n) {}
MyException(const char *s, const char *c)
: source(s), number(0), cause(c) {}
const char *what() const throw()
{
if (number != 0) {
char buffer[1024];
// why does this not work?
cause = strerror_r(number, buffer, 1024);
}
// how to concatenate the strings?
return source + ": " + cause;
}
};
您可以存储std::string
,但仍从 what 函数返回const char *
。
struct MyException : public std::exception
{
private:
std::string message;
public:
MyException(const char *s, int n) {
char buffer[1024];
strerror_r(n, buffer, 1024);
message.reserve(strlen(s) + 2 + strlen(buffer));
message = s;
message += ": ";
message += buffer;
}
MyException(const char *s, const char *c) {
message.reserve(strlen(s) + 2 + strlen(c));
message = s;
message += ": ";
message += c;
}
const char *what() const throw()
{
return message.c_str();
}
};
只需使用 string.h 中的strcat()
和strcpy()
函数。
http://www.cplusplus.com/reference/clibrary/cstring/strcat/http://www.cplusplus.com/reference/clibrary/cstring/strcpy/
此外,由于您不必修改原始字符串,因此const char*
和char*
之间的差异无关紧要。
另外,不要忘记malloc()
(保留空间(目标字符串的所需大小。
这就是我实现它的方式:
struct MyException : public std::exception
{
public:
const char *source;
int number;
const char *cause;
private:
char buffer[1024]; // #1
std::string message; // #2
std::string build_message() {
if (number != 0) {
cause = strerror_r(number, buffer, 1024); // use the member buffer
}
std::string s; // #3
s.reserve(strlen(source) + 2 + strlen(cause));
return s + source + ": " + cause;
}
public:
MyException(const char *s, int n)
: source(s), number(n), cause(), message(build_message()) {}
MyException(const char *s, const char *c)
: source(s), number(0), cause(c), message(build_message()) {}
const char *what() const throw()
{
return message.c_str(); // #4
}
};
注意事项:
原始代码使用局部变量作为缓冲区。这是一个坏主意,因为存储在
cause
中的指针在作用域结束时将无效。对于串联的消息,需要动态分配。这也意味着需要清理该存储。我抓住了一个现有的工具,可以做到这一点并提供类似字符串的操作:
std::string
.使用
std::string
可以使用+
运算符完成串联。请注意我如何要求它为预期大小保留内存。这是内存优化,不是必需的:无论哪种方式,字符串都会分配足够的内存。what
不能引发异常,否则会出现调用std::unexpected
。因此,此处无法分配字符串。
如果必须使用char*
指针,则需要使用 strcat
。 strcat
接受两个参数 char*
和一个const char*
,并将const char*
指向的字符串附加到char*
上。这意味着您首先需要复制第一个字符串。
您需要执行以下操作:
char* Concatenate(const char* first, const char* second)
{
char* mixed = new char[strlen(first) + strlen(second) + 2 /* for the ': ' */ + 1 /* for the NULL */];
strcpy(mixed, first);
strcat(mixed, ": ");
strcat(mixed, second);
return mixed;
}
这不就是丑陋吗?而且,请记住,由于您已经动态分配了该函数返回的 char*,因此调用方必须记住delete[]
它。这种丑陋和确保调用方以正确的方式清理的需要是你最好使用字符串实现(如 std::string
(的原因。
分配大小strlen(source) + strlen(cause) + 3
的缓冲区并使用sprintf
创建消息。实际上,您可以将此代码移动到构造函数中,以便what
变得简单。
如果你真的必须使用 c 字符串,你应该看看strcat()
将它们连接在一起。但是,由于您正在创建自定义异常,因此考虑改用std::string
是合理的,因为它在C++中使用更友好。
- 如何将一个ostringstream十六进制字符串字符对转换为单个unit8t等价的二进制值
- 尝试将字符串/字符转换为整数会产生意外结果
- 为什么没有访问所有字符串字符?
- 将子字符串字符从字符串值转换为 int,然后将其分配给 int 变量
- 如何将字符串字符与结构数组进行比较?
- 将单个字符串/字符输入串行监视器
- 读取字符串字符时出错 - 对于数组中的字符串值
- C++ C 样式字符串/字符数组的大小 - 优化
- 读取字符串字符时出错
- C++ 使用 Strtok 读取字符串字符时出错
- 如何将 int 数组的 1 个元素转换为字符串/字符
- 在另一个字符串中逐个复制字符串字符
- 将字符串字符映射到矢量
- MBED RTOS将Float转换为字符串/字符阵列
- 如何使用字符串字符数组中的 ++ 运算符访问下一个字符串
- 如何比较C++中的单个字符串字符?
- 内部字符串/字符如何在 int 和 float 中存储
- 将十六进制转换为可打印的字符串/字符
- wcscpy_s后读取字符串字符时出错
- 检查字符串字符和长度