1

I have multiple sentences which are being printed in the console currently. I have to gather them into a string.

A part of the code is:

#include <stdio.h>
#include<string.h>

int main()
{
    char buffer [100];
    sprintf (buffer, "%d plus %d is %d", 5, 3, 5+3);
    char *c=buffer;
    sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3);
    strcat(c, buffer);
    printf ("[%s]",c);
    return 0;
    return 0;
}

I tried to create formatted string using sprintf, but the result is wrong. The length of the sentences and their count are unlimited.

I want the output from the above code to be like:

[5 plus 3 is 8and 6 minus 3 is 3]

But it is:

[and 6 minus 3 is 3and 6 minus 3 is 3]

How do I need to concatenate them? Also, the length of the sentences and their count are unlimited. I have difficulties in using malloc and realloc. Can anyone help?

Enchantres
  • 853
  • 2
  • 9
  • 22

2 Answers2

5

sprintf (buffer, "and %d minus %d is %d", 6, 3, 6-3); re-writes buffer instead of concatenating. The original result of the previous sprintf() is lost.

strcat(c, buffer);appends buffer to itself. As that overlaps, it is undefined behavior (UB). Do not do that.


Instead use the return value of sprintf() (number of characters printed) to determine the offset printing.

int offset = sprintf (buffer, "%d plus %d is %d", 5, 3, 5+3);
offset += sprintf (buffer + offset, " and %d minus %d is %d", 6, 3, 6-3);
offset += sprintf (buffer + offset, " even more");
printf ("[%s]",buffer);

Avoid strcat() as that requires code to iterate down the prior string, resulting in Schlemiel the Painter's Algorithm. Better to keep track of the string length and use that for the next sprintf().


Better code could use snprintf() to prevent buffer overrun.

// Pedantic example
char buffer [100];
size_t offset = 0;
size_t available = sizeof buffer;

int retval = snprintf (buffer, available, "%d plus %d is %d", 5, 3, 5+3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

retval = snprintf (buffer + offset, available, " and %d minus %d is %d", 6, 3, 6-3);
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

retval = snprintf (buffer + offset, available, " even more");
if (retval < 0 || (unsigned) retval >= available) Handle_Overflow();
offset += retval;
available -= retval;

printf ("[%s]",buffer);

length of the sentences and their count are unlimited.

Usually a large buffer is sufficient as unlimited is not really unlimited, just potentially large. C strings are limited to SIZE_MAX.

Alternative: research non-C standard asprintf().

Oka
  • 23,367
  • 6
  • 42
  • 53
chux - Reinstate Monica
  • 143,097
  • 13
  • 135
  • 256
  • 1
    Of course with the admonition to check that `offset` plus the anticipated length of the string literal and conversions doesn't exceed the buffer size (minus 1). (you got it whilst I was pecking away...) – David C. Rankin Jul 27 '21 at 14:59
  • @DavidC.Rankin True, hence the "Better code could use snprintf()" part of the answer. I would have detailed that for OP, yet wanted to address the non-`strcat()` solution first. – chux - Reinstate Monica Jul 27 '21 at 15:01
  • If you are old enough, you will remember a sit-com who's intro used `"Schlemiel"` in two different pronunciations and a reference to "Hasenpfeffer Incorporated" `:)` – David C. Rankin Jul 27 '21 at 15:05
  • @DavidC.Rankin [Surely](https://www.imdb.com/title/tt0074016/) you can't be serious - and [stop calling me Shirley](https://www.youtube.com/watch?v=KM2K7sV-K74). ;-) – chux - Reinstate Monica Jul 27 '21 at 15:08
1

Good program needs nice design.Simplify it.

#include <stdio.h>
#include <string.h>

int main()
{
    fprintf(stdout, "%d plus %d is %d", 5, 3, 5+3);
    fprintf (stdout, "and %d minus %d is %d", 6, 3, 6-3);
    return 0;
}

In order to deal with the unlimited problem, you can output to a file or other.

Y.Jie
  • 148
  • 1
  • 8
  • This answer is a bit like telling someone who wants to learn to swim that they should go for a run instead. Learning how to move data around in buffers, and understanding exactly how much and where you're placing data are very valuable skills in C. Sidestepping the issue doesn't do much to teach how to work through this problem. – Oka Jul 27 '21 at 14:59
  • Do you think he needs to learn'malloc' or'realloc' through this question? – Y.Jie Jul 27 '21 at 15:05
  • It's certainly an option, not the definitive answer, but it could offer insight on a different way to approach the problem. chux's answer has an example of maintaining bounds and offsets on a stack allocated buffer, perhaps you could show us how to solve this with dynamically allocated memory? Either way, your current answer is an answer to a completely different question (namely, *How do I print interpolated data?*), having nothing to do with string concatenation. – Oka Jul 27 '21 at 15:56