1

I have the following C example:

char *message;
char *name = "John";
int age = 100;

message = "Hello, I am John, age 100"; 

How to put name and age as parameters in message?

Pseudo codemessage = "Hello, I am {name}, age {age}"

UPDATE

I tried the following example from comments:

char *body = "{ \"capabilities\": {},\"desiredCapabilities\": {}}";
int content_length = sizeof(body);

char *format = "POST /session HTTP/1.1\r\nContent-Type: application/json\r\nContent-Length:%d\r\n\r\n%s";
int len = snprintf(NULL, 0, format, content_length, body);
char *message = malloc(len + 1);
snprintf(message, len + 1, format, content_length, body);

But I am getting error at char *message = malloc(len + 1);:

error: invalid conversion from ‘void*’ to ‘char*’ [-fpermissive]|

CuriousGuy
  • 1,545
  • 3
  • 20
  • 42
  • 2
    C or C++? Also, if C++ can you use `std::string`? – NathanOliver Aug 15 '17 at 17:58
  • 1
    Use `std::string` instead. Then you can use `+` operators and `std::to_string`. – Weak to Enuma Elish Aug 15 '17 at 17:58
  • I updated the question. It is about `C` – CuriousGuy Aug 15 '17 at 17:58
  • 1
    Just char *name = "John"; should give a warning because it is a char const * – Antoine Morrier Aug 15 '17 at 17:59
  • 2
    If in C, do you know how to output it with `printf`? Have you heard about [`sprintf` (or the more preferred `snprintf`)](http://en.cppreference.com/w/c/io/fprintf)? – Some programmer dude Aug 15 '17 at 17:59
  • 1
    @AntoineMorrier Not invalid in C unfortunately, IIRC one has to enable extra warnings for that. – Some programmer dude Aug 15 '17 at 18:00
  • @Someprogrammerdude could you please give me a specific example of my case, because I tried with `sprintf` but since `*message` is immutable, it threw `segmentation fault` – CuriousGuy Aug 15 '17 at 18:02
  • `message` isn't immutable, it's an uninitialised pointer that doesn't point anywhere valid. Make message a char buffer, e.g. `char message[80];` and use that. And use `snprintf` instead of `sprintf` to prevent buffer overflow. – M Oehm Aug 15 '17 at 18:04
  • No `message` (or `*message`) is immutable, instead it's *not initialized* which means the contents of `message` is *indeterminate* if it's a local variable inside a function (and a null pointer if defined globally) and attempting to dereference that pointer (which `sprintf` and the related `snprintf` does) leads to *undefined behavior*. – Some programmer dude Aug 15 '17 at 18:14
  • And if you don't know about the uninitialized status of local variable, or how to allocate memory dynamically, then I suggest you take a couple of steps back, and [find a couple of good beginners books to read](http://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list), and start over. – Some programmer dude Aug 15 '17 at 18:16

1 Answers1

4

You can do this with the snprintf. This works like printf, but puts the result into a string instead of writing it to stdout.

char message[100];
snprintf(message, sizeof(message), "Hello, I am %s, age %d", name, age);

Note that this example uses a fixed size buffer. If you want to dynamically allocate the space, you could do this:

const char *format = "Hello, I am %s, age %d";
int len = strlen(format) + strlen(name) + sizeof(age)*3 + 1;
char *message = malloc(len);
snprintf(message, len, "Hello, I am %s, age %d", name, age);
// ...
free(message);

This sets aside space for the format string, each parameter, and the terminating null byte.

Another way of getting the needed length is to call snprintf twice, the first time with NULL for the string and 0 for the size. The return value is the length of the resulting string:

const char *format = "Hello, I am %s, age %d";
int len = snprintf(NULL, 0, "Hello, I am %s, age %d", name, age);
char *message = malloc(len + 1);
snprintf(message, len + 1, "Hello, I am %s, age %d", name, age);
// ...
free(message);

Regarding the error in your updated code, you're apparently using a C++ compiler instead of a C compiler. If you're writing C, use a C compiler.

Jarod42
  • 203,559
  • 14
  • 181
  • 302
dbush
  • 205,898
  • 23
  • 218
  • 273
  • 1
    You don't need the `-1`; `snprintf` accounts for the terminating null. – M Oehm Aug 15 '17 at 18:05
  • Maybe you could say that he could dynamicaly allocate the memory with malloc – Antoine Morrier Aug 15 '17 at 18:05
  • @CuriousGuy: You would have to use `malloc` or `calloc` to set aside the space for the final string and assign the resulting pointer to `message`. – John Bode Aug 15 '17 at 18:07
  • (As a note: You can do without the handish length calculation and call `len = snprintf(NULL, 0, ...)` to get the required length, excluding the terminating null this time.) – M Oehm Aug 15 '17 at 18:11
  • @MOehm Correct. Removed the -1 in the initial example and added an example of using `snprintf` to get the length. – dbush Aug 15 '17 at 18:20
  • @dbush Could you please take a look at my answer to the question? I wrote an answer because it is too long for a comment. – CuriousGuy Aug 15 '17 at 18:34
  • 1
    @CuriousGuy You're using a C++ compiler instead of a C compiler. – dbush Aug 15 '17 at 18:42
  • @dbush, yes, thank you. I changed to `C` compiler and it run. But I have problem with `int content_length = sizeof(body);` as it returns `8`, the size of the pointer, as `chux` commented. How can I get the size of the `body` string itself? – CuriousGuy Aug 15 '17 at 18:49
  • @CuriousGuy Use `strlen` to get the length of a string. – dbush Aug 15 '17 at 18:51