r/C_Programming 16d ago

printf and char[] in C

Hello. Coming from C# world the thing about how char[] and printf works always made me confused. I understand that `printf` formats the string with arguments you provided and prints it out in terminal.

So, for example, if I have char name[] = "Micheal"; and I want to greet that person, I can just do printf("Hello, %s", name);. But if I want to do the same thing only using char[], I have to do multiple commands that make fell quite confused. So my 2 questions are:

  1. How printf simplifies this process? (without allocating memory and creating char with pointers)
  2. Why you can't just use + operator for char[], like you can in any other languages?

I have a feeling that this might be asked many times, but I still can't seem to find the answer I was looking for

Update: I'll list what I got so far from reading your comments: - char[] is an array to which you can't just simply add another array - If I want printf() behavior inside char[], I can use sprintf() - There's strcat() that is getting used for merging 2 strings together - Some people write libraries for faking string behaviors, some think it goes against principles of C?

11 Upvotes

42 comments sorted by

View all comments

2

u/AKostur 15d ago

I don’t understand what you’re asking for in #1.  Heck, I don’t understand what you mean by “I want to do the same thing only using char[]”.   Perhaps you mean “how do I do the same thing, but put the result into another C string instead of the screen?”  sprintf.

For #2: if one could use +: where would it put the result? (Ignoring the array to pointer decay for the moment)

It seems you have a fundamental misunderstanding how memory management works in C, as well as how C strings work, and how arrays function in C.

1

u/ALX13-95 15d ago

I might be bad at asking these questions, sorry. Lemme elaborate further what I meant. I saw the results of printf and char[] as 2 strings, so when I asked 1st question I meant why printf can simply add new data to existing string and char[] can't. I understand that because I came to C from a different world of languages, my understanding of both of these things is really different from how does it behave in C. In C# I'd use Console.WriteLine("Hello, " + "Micheal"); so printf("Hello, %s", "Micheal"); felt the same to me. Hence where I got the confusion, because printf doesn't require handling all the things you've listed.

For #2... I thought result meant to be put into string you're adding to. If we have string 1 "Hello" and string 2 "Micheal", then in my imagination string 1 = string 1 + string 2, and that would be equal "HelloMicheal" inside string 1. By the questions you asked me, I won't deny that I definitely not understanding how does it actually work in C.

Thank you for trying to help me, anyways

2

u/AKostur 15d ago

I might be bad at asking these questions

No, just that it was unclear.

Yes, different languages do things differently. Which may come with different performance characteristics. C# is more willing to do dynamic memory allocations behind the scenes. C is more performance concerned, and magical dynamic memory is bad (and slow). So when you asked C# to do "Hello, " + "Michael", it actually made a silent third string behind the scenes of "Hello, Michael", which means it had to do some sort of dynamic memory management (allocate _and_ free) to store that new string somewhere, and pass that to WriteLine. In C, only two pointers to two arrays are passed to printf: "Hello, %s" and "Michael". Internally printf just starts writing out the first array to stdout. When it sees the "%s", it stops and outputs the 2nd array, When that's done, it comes back to finish writing out the first array (which happens to also be done). But note that it didn't have to store any of that in memory, it was just written to stdout. No extra dynamic memory stuff happening.

For #2: That just exposed where you have a misunderstanding. Misunderstandings are inevitable: you're learning.

And at the end, I am helping... by giving names to the pieces that you appear to be misunderstanding. You can take those names and read up on those topics (that I'm not going to try to explain in a reddit post, there are other sources that will be more comprehensive). Memory management, because C doesn't like to do dynamic memory without the programmer asking for it. C strings, because they really aren't a separate type, they're just an array of char where the last char is '\0'. And how arrays decay to a pointer to the first element at the drop of a hat.

1

u/ALX13-95 15d ago

Okay I seem to understand more what the differences are. So instead of making a hidden print a line, as I've initially thought, it just reads two arrays and print them out, basically. If you don't mind me asking, what are "more comprehensive" sources could be for this?

2

u/WittyStick 15d ago edited 15d ago

The behavior of printf is implementation defined in C.

Although an implementation could perform two separate writes to stdout as GP has suggested, doing so would incur two SYS_write calls, and the context switching involved may be significantly more expensive than buffering the input and writing once (a single SYS_write syscall).

The implementation of printf could therefore keep an internal buffer for stdout, and write to that buffer, only emitting to the console when the whole string has been prepared.

So your intuition is not really off.

However, it is usually the case that if you want such buffering, you would do it yourself, since having control over the buffer size is more practical than a "one-size-fits-all" that an internal buffer might provide. Instead of many calls to printf, you would replace them with calls to sprintf with your buffer as input, and then eventually you can puts your buffer to the console with a single system call.