如何连接两个char *但没有库函数,我希望更好地了解这个函数的工作原理。
S1 =“AA”
S2 =“BB”
该函数应返回指向“AABB”;
的指针这是我已有的代码。
char * concatenate(char * s1, char * s2)
{
char * p = new char(string_length(s1) + string_length(s2) + 2);
return p ;
}
int string_length(char * s)
{
unsigned int i = 0;
while (*s++ != '\0')
++i;
return i;
}
提前致谢
答案 0 :(得分:2)
这是一种方法:
char *
。char *
的其余部分。\0
以表示字符串终止。另见本帖的所有评论!
size_t string_length(const char * s)
{
size_t i = 0;
while (*s++ != '\0')
++i;
return i;
}
char * concatenate(const char * s1, const char * s2)
{
size_t l1 = string_length(s1);
size_t l2 = string_length(s2);
/// Step 1:
char * p = new char[l1 + l2 + 1];
/// Step 2:
for (size_t i = 0; i < l1; i++) {
p[i] = s1[i];
}
/// Step 3:
for (size_t i = 0; i < l2; i++) {
p[i + l1] = s2[i];
}
/// Step 4:
p[l1 + l2] = '\0';
return p;
}
int main()
{
char* test = concatenate("first", "second");
cout << test;
/// Delete after use.
delete[] test;
cin.get();
return 0;
}
答案 1 :(得分:1)
要连接两个char
字符串,需要做出一些设计决策。
最关键的是你是否希望串联功能的用户提供他们自己的存储区来保存字符串,或者你想自己提供足够大的区域。
让用户提供区域的好处是用户可以选择连接字符串的去向,用户可以决定如何管理内存。
因此,我们创建几个相关的功能,提供此功能,并允许用户决定他们需要多少或几乎没有帮助。
template <typename T>
size_t Str_len(const T *s1)
{
const T *const sStart = s1;
if (s1) while (*s1) s1++; // guard against nullptr
return s1 - sStart;
}
template <typename T>
T *Str_alloc(size_t nChars)
{
T * p = new T[nChars + 1]; // plus 1 for end of string character
p && nChars > 0 && (*p = 0); // initialize new string with end of string if possible
return p;
}
template <typename T>
void Str_delete(T *src)
{
delete [] src; // new array requires delete array
}
template <typename T>
T *Str_cpy(T *dest, const T *src)
{
T * const destStart = dest; // will return beginning of dest
if (src && dest) {
while (*dest++ = *src++); // copy from src to dest including end of string
}
return destStart;
}
template <typename T>
T *Str_cat(T *dest, const T *src)
{
if (src && dest) {
T * const destStart = dest; // will return beginning of dest
while (*dest) dest++; // find end of string of dest
Str_cpy(dest, src); // copy src to end of dest
return destStart ;
}
else {
return dest; // bad args so just return dest
}
}
template <typename T>
T *Str_cat_alloc(const T *s1, const T *s2)
{
size_t nChars = Str_len(s1) + Str_len(s2);
auto dest = Str_alloc <T> (nChars);
if (dest && s1) {
Str_cpy(dest, s1);
if (s2) {
Str_cat(dest, s2);
}
return dest;
}
else {
return dest;
}
}
这些将用于:
int main(int argc, char * argv[])
{
auto p1 = Str_alloc <char> (28);
auto p2 = Str_alloc <char>(32);
Str_cpy(p1, "this test");
Str_cpy (p2, p1);
Str_cat (p2, "xxx");
auto p3 = Str_alloc <char> (Str_len(p1) + Str_len(p2));
Str_cat (p3, p1);
auto p4 = Str_cat (p3, p2);
auto p5 = Str_cat_alloc("this is one ", "this is two");
Str_delete (p1);
Str_delete (p2);
Str_delete(p3);
// no delete on p4 as it is a copy of p3
// see how confusing C style memory management can be?
Str_delete(p5);
return 0;
}
附录:使用可变参数模板
这是使用可变参数模板的另一个例子,它以令人愉快的方式允许可变数量的参数。此示例已使用Visual Studio 2017 Community Edition进行编译和测试。
template <typename T>
T *Str_cat(T *a, const T * b)
{
T *pSave = a;
while (*a) a++;
while (*a++ = *b++);
return pSave;
}
template <typename T, typename... Args>
T *Str_cat(T *a, const T *b, Args... args)
{
T *pSave = a;
while (*a) a++;
for (; *a = *b; a++, b++);
Str_cat(a, args...);
return pSave;
}
template <typename T>
size_t Str_len(T *a)
{
T *pSave = a;
while (*a) a++;
return a - pSave;
}
template <typename T, typename... Args>
size_t Str_len(T *a, Args... args)
{
return Str_len(a) + Str_len(args...);
}
这些功能可以如下使用。
int main (int argc, char *argv)
{
char p[] = "this is p1";
char p2[] = "this is p2";
char p3[] = "this is p3";
char p4[] = "this is p4";
char p5[] = "this is p5";
char bigbuff[512];
auto i = Str_len(p, p2, p3, p4);
bigbuff[0] = 0;
Str_cat(bigbuff, p, p2, p3);
bigbuff[0] = 0;
Str_cat(bigbuff, p, p2, p3, p4, p5);
return 0;
}