2012-03-28 15 views
8

文字リテラルとcharリテラルを連結したい。文法的に間違っている、"abc" 'd' "efg"は、コンパイラエラーをレンダリング:今では文字リテラルをcharリテラルと連結する

x.c:4:24: error: expected ',' or ';' before 'd'

私は、文字列の値リテラルと文字リテラルされているにもかかわらず、(不)snpriftを使用する必要がコンパイル時に知っています。

私は

#define CONCAT(S,C) ({ \ 
    static const char *_r = { (S), (C) }; \ 
    _r; \ 
}) 

を試みたが、Sのヌルターミネータが取り除かれていないので、それは動作しません。 (コンパイラの警告を与えることのほかに。)

マクロは

  • "abc" MACRO('d') "efg"または
  • MACRO1(MACRO2("abc", 'd'), "efg")または
  • MACRO("abc", 'd', "efg")を使用することを書くための方法はありますか?

誰かが私にそれをしたいと尋ねる場合:charリテラルはライブラリから来ているので、文字列をステータスメッセージとして出力する必要があります。

+0

私は* *はsprintfまたは任意のランタイム関数を使用したいしたくありません。ランタイムメソッド呼び出しを使用する答えは入れないでください。 – kay

+0

リテラルがライブラリから来た場合、どのようにアクセスしていますか?それはライブラリヘッダーファイルによって提供されるマクロですか? –

+0

はい、ヘッダーファイルからのものです。 – kay

答えて

2

Cでは、文字列リテラルのみを連結できます。実際には、snprintf()は何も問題ありません。またstrcpy()を使用することができます。

strcpy(dest, str1); 
dest[strlen(dest)] = c; 
strcpy(dest + strlen(dest) + 1, str2); 

ます。また、この制限を克服するために巨大なswitchステートメントを使用することができます

switch(c) { 
    case 'a': 
     puts("part1" "a" "part2"); 
     break; 
    case 'b': 
     puts("part1" "b" "part2"); 
     break; 

    /* ... */ 

    case 'z': 
     puts("part1" "z" "part2"); 
     break; 
} 

...しかし、私はすべての著作を主張することを拒否します。

簡潔に言えば、snprintf()と貼り付けてください。それは実際にあることを納得させる限り、または適切なであってもなくてもよい状況に応じて、

#define SOME_DEF 'x' 

#define STR1(z) #z 
#define STR(z) STR1(z) 
#define JOIN(a,b,c) a STR(b) c 

int main(void) 
{ 
    const char *msg = JOIN("Something to do with ", SOME_DEF, "..."); 

    puts(msg); 

    return 0; 
} 

、しかし:あなたは、単一引用符は、それに含まれていると一緒に暮らすことができる場合

+0

私は* snprintfやstrcpyを使用したくないということです。初心者の質問よりも哲学的な質問のほうが多いです... – kay

+1

kay:ああ、私は...幸運を! ;)BTW、 'printf(" part1%c part2 \ n "、c);の何が問題なのですか? – Philip

+1

printfには何も「間違っている」というものはありません。私はちょうどそれがコンパイル時にすべての実行時のアクティビティなしで文字列全体を取得することが可能かどうかを知りたがっています。このようなマクロを持っているかどうかは問題ではありません。あなたが見る...それは哲学的な質問です。 ;) – kay

6

、あなたは文字列化を使用することができますこのように文字列リテラルを使用すると、実行時に書式設定しなくても気になる唯一の方法です。

+0

JOIN(a、b、c)のように連結でSTR1を直接使用しないでくださいSTR1(b)c?サブマクロSTR()を使用する代わりに? – Luciano

3

これを試してください。それはダブルマクロのCマクロトリックを使用するので、マクロ引数は文字列化される前に拡張する機会があります。

#include <stdio.h> 

#define C d 
#define S "This is a string that contains the character " 
#define STR(s) #s 
#define XSTR(s) STR(s) 

const char* str = S XSTR(C); 

int main() 
{ 
    puts(str); 
    return 0; 
} 
3

私は1つがnestedly CONCATを使用することはできませんように私は、あまり好きではないGCC固有のソリューションを思い付きました。

#include <stdio.h> 

#define CONCAT(S1,C,S2) ({      \ 
    static const struct __attribute__((packed)) { \ 
     char s1[sizeof(S1) - 1];     \ 
     char c;         \ 
     char s2[sizeof(S2)];      \ 
    } _r = { (S1), (C), (S2) };     \ 
    (const char *) &_r;       \ 
}) 

int main(void) { 
    puts(CONCAT ("abc", 'd', "efg")); 
    return 0; 
} 

http://ideone.com/lzEAn

+1

gccで '-pedantic'オプションを指定してコンパイルすると、"配列はカッコで囲まれた文字列定数から初期化されます "と" ISO Cは式内でブレースされたグループを禁止します "という警告が表示されます。 –

関連する問題