Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate string literal with char literal

I want to concat a string literal and char literal. Being syntactically incorrect, "abc" 'd' "efg" renders a compiler error:

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

By now I have to use snprift (needlessly), despite the value of string literal and the char literal being know at compile time.

I tried

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

but it does not work because the null terminator of S is not stripped. (Besides of giving compiler warnings.)

Is there a way to write a macro to use

  • "abc" MACRO('d') "efg" or
  • MACRO1(MACRO2("abc", 'd'), "efg") or
  • MACRO("abc", 'd', "efg") ?

In case someone asks why I want that: The char literal comes from a library and I need to print the string out as a status message.

like image 286
kay Avatar asked Mar 28 '12 16:03

kay


People also ask

Can we concatenate string and character?

Concatenating strings would only require a + between the strings, but concatenating chars using + will change the value of the char into ascii and hence giving a numerical output.

Can you concatenate to a string literal?

String literalsThe code concatenates the smaller strings to create the long string literal. The parts are concatenated into a single string at compile time.

How do I concatenate two characters to a string?

2) String Concatenation by concat() method The String concat() method concatenates the specified string to the end of current string. Syntax: public String concat(String another)

What is char in string literal?

1) character string literal: The type of the literal is char[N], where N is the size of the string in code units of the execution narrow encoding, including the null terminator. Each char element in the array is initialized from the next character in s-char-sequence using the execution character set.


2 Answers

If you can live with the single quotes being included with it, you could use stringification:

#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;
}

Depending on the context that may or may not be appropriate, but as far as convincing it to actually be a string literal buitl this way, it's the only way that comes to mind without formatting at runtime.

like image 87
FatalError Avatar answered Oct 08 '22 00:10

FatalError


I came up with a GCC-specific solution that I don't like too much, as one cannot use CONCAT nestedly.

#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

like image 31
kay Avatar answered Oct 08 '22 02:10

kay