フレキシブルにお客様のご要望にあわせ提供します.

文字列を連結する strcat の可変長引数版(C言語)と その template 化 (C++)

目的

  1. (ポインタを使う一例として)、strcat より機能が高い、たとえば可変長引数で無数連結できる関数 combStrを strcat を用いずに C言語で作ります。
  2. (Templete を使う例として)作った combstr の wchar 版も作成し、char, wchar をテンプレートによりまとめ、ワイド文字列にも対応したものにします

 

 

C++であれば STL の vector クラスを使うのがふつうだと思いますが、ここではあえてポインタでそれをやってみるということです。


	template <typename T>
unsigned int mylen(T* str){
    unsigned int i = 0; while (str[i] != 0x00)
    {
        i = i + 1;
    }
     
    if (typeid(T) == typeid(wchar_t)){ return 2 * i; }
    else{ return i; }
 
}
template unsigned int mylen(char*s);
template unsigned int mylen(wchar_t*s);
 
 
 
template <typename T>
T**  CreChrArray(DWORD num){
    return (T **)calloc(sizeof(T*) * (num + 1), sizeof(T*));
}
template char** CreChrArray(DWORD num);
template wchar_t** CreChrArray(DWORD num);
 
 
 
template <typename T>
T*  CreChr(DWORD num){
    return (T*)calloc(sizeof(T)*num, sizeof(T));
}
template char* CreChr(DWORD num);
template wchar_t* CreChr(DWORD num);
 
 
 
 
template <typename T>
unsigned int getByteChrArray(T** s){
    unsigned int i = 0, b = 0;
    while (s[i] != 0) {
        b = b + mylen<T>(s[i]);
        i = i + 1;
    }
 
    return b;
 
}
template unsigned int getByteChrArray(char**s);
template unsigned int getByteChrArray(wchar_t**s);
 
 
 
template <typename T>
T* combStr(T *s, ...){
    unsigned char c = 1;
    if (typeid(T) == typeid(wchar_t)){
        c = 2;
    }
 
 
    int i = 0;
    T **a = CreChrArray<T>(i);
    va_list ap;
    va_start(ap, s);
    do {
        i = i + 1;
        a = (T **)realloc(a, (i + 1) * sizeof(T *));
        a[i - 1] = s;
        s = va_arg(ap, T*);
    } while (s);
 
    va_end(ap);
 
    a[i] = 0x00; //旧 a[i]="\0";
 
    int bi = getByteChrArray<T>(a);
    int p = 0;
    T* str = CreChr<T>(bi);
 
 
    for (int j = 0; j < i; j++){
 
        memcpy(str + p, a[j], mylen<T>(a[j]));
 
        if (j < i) { p = p + mylen<T>(a[j]) / c; }
        else{ break; }
    }
 
    str[p] = 0x00;
 
    free(a);
 
    return str;
}
template char* combStr(char *s, ...);
template wchar_t* combStr(wchar_t *s, ...);