0

In Python I can do this:

print("Hello, %s!" % username)

How do I in C++ do the similar thing? I can do this, but it's probably not a good practice:

void welcome_message(std::string username) {
    std::cout << "Hello, " << username << "!" <<std::endl;
}
Treoad
  • 3
  • 2
  • 3
    _"but it's probably not a good practice"_ Why not? – πάντα ῥεῖ Apr 15 '16 at 14:07
  • 3
    That is probably the best thing you can do in C++, as soon as you accept `username` by const reference rather than value. – SergeyA Apr 15 '16 at 14:07
  • 1
    _"In Python I can do this"_ No, you can't, because you have a syntax error. – Lightness Races in Orbit Apr 15 '16 at 14:09
  • I don't know C++ that well, but would it not be cleaner way to write out the whole string and add for example %s inside it? So I don't use a "new" string with only "!" in it? – Treoad Apr 15 '16 at 14:09
  • Python got rid of format specifiers as well, among the other things. – edmz Apr 15 '16 at 14:09
  • @Treoad: That "'new' string with only '!' in it" is a single byte (okay, maybe two, depending on storage scheme) statically allocated within your executable. Don't worry about it. – Lightness Races in Orbit Apr 15 '16 at 14:10
  • And forget even the word **best practices**. This is the third time I am saying it in the last 2 days. Just forget it and never use it. Go from problem to solution. – SergeyA Apr 15 '16 at 14:10
  • @LightnessRacesinOrbit: Yes, the comma. – Treoad Apr 15 '16 at 14:10
  • @SergeyA: What is this nonsense? Forget best practices? Great way to go from problem to utterly horrific solution. Please don't teach people to develop software in this manner. – Lightness Races in Orbit Apr 15 '16 at 14:11
  • @Treoad: Sorry, but you are wrong. Copy/paste it into a Python script and attempt to run it. You'll see the error soon enough. – Lightness Races in Orbit Apr 15 '16 at 14:11
  • 1
    @LightnessRacesinOrbit, yes. I hate **best practices**. They are only best in someone's mind, and more often than not, they are terribly misguided (consider - Best practice is to use singletons instead of global variables). Instead, one should know the problems associated with particular solutions and how other solution is better. Not because it is *best practice*, but because doing this will cause that. – SergeyA Apr 15 '16 at 14:12
  • @SergeyA: That's literally what a best practice is, lol – Lightness Races in Orbit Apr 15 '16 at 14:13
  • @LightnessRacesinOrbit, to go by example, it is not **best practice** to wash one's hands after visiting bathroom. It is a very specific action, which washes out germs and protects from diseases. – SergeyA Apr 15 '16 at 14:14
  • 1
    @LightnessRacesinOrbit, I am talking about a particular form of best practice, omnipresent everywhere - when all rationale is lost, and all the reasoning is lost, and someone is just saying - 'as enlighted guru said, it is best practice to...'. And more often than not this is exactly what I see here. – SergeyA Apr 15 '16 at 14:16
  • 1
    @SergeyA: Then you're making a strawman because you're arguing against something other than what everybody else understands "best practice" to mean. Also, your example is kind of strange: I think it's most _certainly_ a best practice to wash your hands after going to the toilet. Please make sure you always do it. – Lightness Races in Orbit Apr 15 '16 at 14:18
  • @LightnessRacesinOrbit No, this is exactly what we see in this particular example. OP simply asking about best practice, without any attempt at understanding why it might be best or worst. Very precise example of what I am talking about. – SergeyA Apr 15 '16 at 14:20
  • @SergeyA: Sorry, I don't argue with people who don't think it's a best practice to wash your hands after going to the loo. – Lightness Races in Orbit Apr 15 '16 at 14:21
  • 2
    @LightnessRacesinOrbit I take his meaning. People will ask what best practice is and then blindly follow it without understanding, applying it where it's not best practice because they don't understand it-- voodoo programming. In the case of this question, the questioner has no clue how C++ characters and strings work and is blindly applying what he thinks is python "best practice". – Rob K Apr 15 '16 at 14:23
  • @RobK: That is not an argument against best practice. It is an argument against being a blind stupid person who doesn't think before they do. Refer to my above comments regarding going to the toilet; best practices most certainly exist and teaching people to always ignore them is both misguided and negligent. – Lightness Races in Orbit Apr 15 '16 at 14:26
  • 1
    @RobK: Yes, I don't have a clue how it works that's why I ask. I wanted to demonstrate a way in Python and get an answer how to do it as I should do it in C++. – Treoad Apr 15 '16 at 14:27
  • @Treoad You'd be better to forget what you know about Python and [get a good C++ book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?lq=1). You'll be happier in the end. – Rob K Apr 15 '16 at 14:33
  • I think I might be able to bridge Lightness and Sergey's points pretty quickly (and I hope I don't regret trying): **good practice** exists, should be known and understood, and should be followed until there is a VERY *VERY* good reason to depart from it. The phrase **best practice** suggests that the practice is *universal without exception*, which isn't the case. Even the phrase "best" is an extreme, along the same lines as "always" and "never". This may seem pedantic for those of us who already know this concept, but for newbies, the devil's in the phrasing. – CodeMouse92 Apr 15 '16 at 19:30

3 Answers3

2

For simple code, you may use std::cout. But this is not very good for localisation and looks kind of ugly.

Boost.Format fixes this by providing functionality very similar to that old Python 2 string formatting feature you demonstrate in your question (which was superseded by str.format()). It's a little like C's printf, except safe.

Here's an example:

#include <string>
#include <iostream>
#include <boost/format.hpp>

void welcome_message(const std::string& username)
{
    std::cout << boost::format("Hello, %s!\n") % username;
}

int main()
{
    welcome_message("Jim");
}

(live demo)

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Boost.Format definitely seems better than `printf`, but I couldn't find its dependencies in the documentation. Is it dependency-free? – Romário Apr 15 '16 at 14:21
  • @Romário: It depends on C++. What dependencies were you looking for? – Lightness Races in Orbit Apr 15 '16 at 14:22
  • Off the top of my head I'm not aware of _any_ Boost libraries with dependencies other than the language itself (and perhaps some OS support). That's kind of the point of them. – Lightness Races in Orbit Apr 15 '16 at 14:23
  • Does it depend on other boost libraries or you can use it standalone? – Romário Apr 15 '16 at 14:23
  • @Romário: I don't understand the distinction. You either have Boost headers installed or you don't. Why would you ever only have a part of Boost installed? Execute `sudo apt-get install libboost-all-dev` on your build machine and you're done. – Lightness Races in Orbit Apr 15 '16 at 14:24
  • lol a downvote for literally answering the OP's question. I love this community – Lightness Races in Orbit Apr 15 '16 at 14:25
  • @LightnessRacesinOrbit "Why would you ever only have a part of Boost installed?" I might be wrong, but not all boost libraries are header-only. I wouldn't want to bring in another library (or more libraries) with my executable just because of this feature. Also, there are some cases where the fewer dependencies, the better, etc.. – Romário Apr 15 '16 at 14:31
  • 1
    @Romário: But these are header-only. They have zero impact on your deployment target. I can understand not deploying all Boost binaries, but that's not relevant here. – Lightness Races in Orbit Apr 15 '16 at 14:32
  • I know it's been a long time, but a problem that should be mentioned with Boost.Format is that it has terrible performance and produces an enormous amount of code bloat: https://github.com/fmtlib/fmt#benchmarks – Romário Aug 19 '16 at 16:55
1
void welcome_message(const std::string& username) {
    std::cout << "Hello, " << username << "!" <<std::endl;
}

is an extremely good thing to do in C++ unless you're doing something particularly performance-critical. Relying on the heavily overloaded << for std::ostream is good practice. It's what it's there for.

Note I've changed the function prototype to avoid an unnecessary string copy. The printf way is littered with dangerous corner-cases: you need to get the formatters exactly correct else you risk the behaviour of your program being undefined.

The only criticism I can levy on this is your use of std::endl. Use "!\n" instead.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
  • 3
    I'm not sure I'd go so far as to call this "_extremely_ good". It's abysmal for localisation and heavy on the function calls. _Boost.Format_ is a safe alternative to `printf` that's worth considering if you're really looking to find the "best" way to do things. It's also the direct equivalent to the OP's Python. – Lightness Races in Orbit Apr 15 '16 at 14:13
1

You can always C's printf:

#include <cstdio>

void welcome_message(const std::string &username) {
    printf("Hello, %s\n", username.c_str());
}

Notice, though, that you have to convert username to a C string using c_str().

As mentioned, using cout and << is pretty standard, but many people argue against it for many reasons (e.g.: iternationalization, readability). So, if you prefer string formatting, there's your option.

Romário
  • 1,664
  • 1
  • 20
  • 30