C 言語で文字列を連結する
この記事では、C 言語で文字列を連結する方法をいくつか説明します。
関数 strcat
と strcpy
を使って C 言語で文字列を連結する
strcat
は、<string.h>
ヘッダで定義されている C 標準ライブラリの文字列機能の一部です。この関数は 2つの char*
引数を取り、2 番目のポインタに格納されている文字列を 1 番目のポインタに追加します。C 言語の文字列の末尾には \0
文字があるので、strcat
はヌル文字から始まる文字列の追加を開始します。最後に、新たに作成した文字列の末尾は \0
で終わる。両方の文字列を格納するのに十分なメモリを宛先ポインタに確保するのはプログラマの役目であることに注意してほしい。
この解決策で利用される 2 番目の関数は strcpy
であり、同様に 2つの char*
パラメータを受け取り、2 番目のポインタにある文字列を 1 番目のポインタにコピーします。strcpy
は、最初の文字列を指定された char
バッファにコピーしてから、そのポインタを strcat
関数に渡すために用いられることに注意してください。
どちらの関数もコピー先の文字列へのポインタを返し、これによりチェーニング呼び出しが可能になります。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef MAX
#define MAX 100
#endif
int main() {
const char* str1 = "hello there 1";
const char* str2 = "hello there 2";
char buffer[MAX];
strcat(strcpy(buffer, str1), str2);
printf("%s\n", buffer);
char buffer2[MAX];
strcat(strcpy(buffer2, "Hello there, "), "Josh");
strcat(buffer2, "!\nTemporary...");
printf("%s\n", buffer2);
exit(EXIT_SUCCESS);
}
出力:
hello there 1hello there 2
Hello there, Josh!
Temporary...
関数 memccpy
を用いて C 言語で文字列を連結する
前者のメソッドの最大の欠点は、strcpy
関数によって格納された最初の文字列に対して冗長な反復処理を行う非効率的な実装であることです。
一方、memccpy
はこの問題を修正し、両方の文字列を効率的に処理します。memccpy
は、ソース文字列の char*
から宛先ポインタへのコピーは、ユーザが指定したバイト数以上は行わず、指定した文字がソース文字列に見つかったときにのみ停止します。memccpy
は、宛先バッファに最後に格納された文字へのポインタを返します。したがって、2つの memccpy
呼び出しは、前のメソッドと同様にチェーンできます。最初の文字列はユーザによってあらかじめ割り当てられたバッファにコピーされ、2 番目の文字列は memccpy
の最初の呼び出しから返されたポインタに追加されます。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef MAX
#define MAX 100
#endif
int main() {
const char* str1 = "hello there 1";
const char* str2 = "hello there 2";
char buffer[MAX];
memccpy(memccpy(buffer, str1, '\0', MAX) - 1, str2, '\0', MAX);
exit(EXIT_SUCCESS);
}
出力:
hello there 1hello there 2
カスタム定義関数を使って C 言語で文字列を連結する
あるいは、memccpy
がプラットフォーム上で利用できない場合は、同じルーチンを実装したカスタム関数を定義することもできます。concatStrings
は、指定された文字が見つかるまでポインタから別のポインタに 1 文字をコピーする実装例です。どちらの例でも、停止する文字としてヌルバイトの \0
を指定していることに注意してください。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef MAX
#define MAX 100
#endif
void* concatStrings(void* restrict dst, const void* restrict src, int c,
size_t n) {
const char* s = src;
for (char* ret = dst; n; ++ret, ++s, --n) {
*ret = *s;
if ((unsigned char)*ret == (unsigned char)c) return ret + 1;
}
return 0;
}
int main() {
const char* str1 = "hello there 1";
const char* str2 = "hello there 2";
char buffer[MAX];
concatStrings(concatStrings(buffer, str1, '\0', MAX) - 1, str2, '\0', MAX);
printf("%s\n", buffer);
exit(EXIT_SUCCESS);
}