在c++中连接两个字符

Joining two characters in c++

本文关键字:两个 字符 c++ 连接      更新时间:2023-10-16

我的要求是连接两个字符。例如

int main()
{
char c1 ='0';
char c2 ='4';
char c3 = c1+c2;
cout<< c3;
}

我期望的数值是04。但我得到的是d。我知道char是单字节的。我的要求是,在C3的单个字节中,可以合并/连接/连接c1、c2,并将值存储为04

char不是string。因此,您可以首先将第一个字符转换为字符串,然后添加下一个字符,如:

int main()
{
char c1 ='0';
char c2 ='4';
auto c3 = std::string(1,c1)+c2;
std::cout<< c3;
}

什么是"魔法"std::string(1,c1):它使用格式为:std::string::string (size_t n, char c);的std::string构造函数。因此,它用给定c1的一个字符"填充"字符串,即0

如果你添加字符,你会得到添加其数值的结果,即:

int main() {
std::cout << (int)c1 << std::endl;
std::cout << (int)c2 << std::endl;
std::cout << (int)c1+c2 << std::endl;
std::cout << char(c1+c2) << std::endl;
}

0中的int值为48,4中的int为52。两者相加,你得到100。100是ascii编码中的CCD_ 9。

您想要的被称为字符串。有很多方法可以在C++中创建它。一种方法是使用标准库中的std::string类:

char c1 = '0';
char c2 = '4';
std::string s; // an empty string
s += c1; // append the first character
s += c2; // append the second character
cout << s; // print all the characters out

char只不过是C++运行时用来显示人类可以阅读的内容的一个积分类型。

所以c1 + c2是一个加两个数字的指令,由于类型转换的规则,它是一个int类型。如果它太大,无法容纳在char中,那么分配给c3将具有实现定义的结果。

如果您想要级联,则

std::cout << ""s + c1 + c2;

从C++11的用户定义的文字来看,这正成为实现这一目标的惯用方式。注意后缀为s

C(和C++)中的每个字符都有一个字节的长度。您正在做的是添加实际的字节值:

'0' = 0x30
'4' = 0x34 
-> '0' + '4' = 0x30 + 0x34 = 0x64 = 'd'

如果你想连接这两个,你需要一个数组:

int main()
{
char c1 ='0';
char c2 ='4';
char c3[3] = {c1,c2,0}; // 0 at the end to terminate the string
cout<< c3;
return 0;
}

请注意,用字符做这些事情是C,而不是C++。在C++中,你会使用字符串,就像克劳斯在回答中所做的那样。

基础知识优先

在C++和C中,字符串以''结尾,称为null字符。该null字符在末尾的存在区分了stringchar阵列。否则,两者都是连续的内存位置。在计算CCD_ 22时,注意不计算最后的CCD_ 23字符。

连接/连接两个字符

如果使用+运算符连接两个字符,那么将注意处理两个字符串末尾的null字符。但是,如果您使用+运算符连接两个char,并希望将其视为string,则不会发生这种情况,因为它的末尾没有null字符。参见以下示例:

char c1 = 'a';
char c2 = 'b';
string str1 = c1 + c2;
cout << str1; // print some garbled character, as it's not valid string.
string str2; // null initialization
str2 = str2 + c1 + c2;
cout << str2; // prints ab correctly.
string s1 = "Hello";
string s2 = "World";
string str3 = s1 + s2;
cout << str3; //prints Hello World correctly.
string str4 = s1 + c1; 
cout << str4; //prints Hello a correctly.

您称之为"joining"的实际上是char类型上的算术,它隐含地将它们提升为int。字符的等效整数值由ASCII表定义("0"为48,"4"为52,因此48+52=100,最后为"d")。当通过+运算符连接文本变量时,您希望使用std::string

你可以做这样的事情:

#include <vector>
#include <iostream>
using namespace std;
int main()
{
char a = '0';
char b = '4';
vector<char> c;
c.push_back(a);
c.push_back(b);
cout << c.data() << endl;
return 0;
}

简单加法不适合"组合"两个字符,您永远无法从22中确定它是否由10和12、11和11、7和15或任何其他组合组成;另外,如果订单是相关的,你永远不会知道它是10和12还是12和10…

现在,可以在数组或std::string中组合您的值(如果表示任意8位数据,您甚至可能更喜欢std::arraystd::vector)。另一种变体是做一些不错的数学运算:

combined = x * SomeFactorLargerThanAnyPossibleChar + y;

现在,您可以通过除法和模计算返回两个值。

假设您只想对ASCII进行编码,128就足够了;考虑到最大值,您得到:127*128+127 == 127*129 == 2^14 - 1。不过,你可能会发现自己的问题:结果可能需要多达14位,因此你的结果将不再适合一个简单的char(至少在典型的现代硬件上,char通常只有8位–不过,周围也有系统,char有16位…)

所以你需要一个更大的数据类型:

uint16_t combined = x * 128U + y;
//^^

旁注:如果使用256,则x和y中的每一个都将被放入uint16_t中的两个的单独字节中。另一方面,如果使用uint64_t和127作为因子,则可以在一个数据类型中组合多达9个ASCII字符。在任何情况下,您都应该始终使用2的幂,这样您的乘法和除法就可以实现为位移,而模计算则可以实现为带有适当掩码的简单and运算。

如果您也使用非ASCII字符,则必须小心:可能会对char进行签名,因此,为了防止在值升级为int时由于符号扩展而产生不必要的影响,您还需要应用强制转换:

uint16_t combined = static_cast<uint8_t>(x) * 128U + static_cast<uint8_t>(y);

由于基本char没有operator+将自己与另一个char连接,

您需要的是使用其他建议的std::string来表示字符串文字

或者在c++17中,您可以使用string_view

char array[2] = {'0', '4'};
std::string_view array_v(array, std::size(array));
std::cout << array_v; // prints 04

https://github.com/bite-rrjo/STG-char-v2/blob/main/stg.h如果没有外部库,它将像这个

#include "iostream"
#include "lib-cc/stg.h"
using namespace std;
int main(){
// sum two char
char* c1 = "0";
char* c2 = "4";
stg _stg;
_stg = c1;
_stg += c2;
cout << _stg() << endl;
// print '04'

}