How do I convert this C line to C++? using cout command - c++

printf("%-8s - %s\n", c->name ? c->name : "", c->help);

I think what you're looking for is
cout << left << setw(8) << (c->name ? c->name : "") << " - " << c->help << endl;
The left and setw(8) manipulators together have the same effect as the %-8s formatting specifier in printf. You will need to #include <iomanip> in order for this to work, though, because of the use of setw.
EDIT: As Matthieu M. pointed out, the above will permanently change cout so that any padding operations print out left-aligned. Note that this isn't as bad as it might seem; it only applies when you explicitly use setw to set up some padding. You have a few options for how to deal with this. First, you could just enforce the discipline that before using setw, you always use either the left or right manipulators to left- or right-align the text, respectively. Alternatively, you can use the flags and setf function to capture the current state of the flags in cout:
ios_base::fmtflags currFlags = cout.flags();
cout << left << setw(8) << (c->name ? c->name : "") << " - " << c->help << endl;
cout.setf(currFlags, ios_base::adjustfield);
This works in three steps. The first line reads the current formatting flags from cout, including how it's currently aligning padded output. The second line actually prints out the value. Finally, the last line resets cout's output flags for internal alignment to their old value.
Personally, I think the first option is more attractive, but it's definitely good to know that the second one exists since it's technically more correct.

If you've got the Boost libraries:
std::cout << boost::format("%-8s - %s\n") % (c->name ? c->name : "") % c->help;

Related

How to format padded signed numbers in a stringstream

I'm trying to format numbers using C++ streams and am having trouble with the sign character being placed after the fill instead of before. When I do this:
std::cout << std::setfill('0') << std::setw(6) << -1;
The output is
0000-1
But what I want is
-00001
With printf I can use a format like "%06d" and it works the way I expect with the sign placed before the zeroes, but I want to get the same effect in a stream and not use the old formatting functions. I can't use C++20 yet either, so std::format isn't available to me yet.
I should have looked a little longer before posting. The answer is the std::internal manipulator, which causes the padding to be done internally within the field. This works correctly:
std::cout << std::internal << std::setfill('0') << std::setw(6) << -1;
-00001

Can strings and integers/floats be mixed when formatting via ostringstream

I'm trying to fully understand how to use ostringstream to modernize some code that uses sprintf. The problem is in replacing test code that generates random or sequential data. Here's a simplified example:
char num[6], name[26];
sprintf(num, "%05d", i);
sprintf(name, "Customer # %d", i);
Leaving aside the minutia of length calculation, copying the result to the array and null-termination, the num conversion is straightforward:
ostringstream ostr;
ostr << setw(len) << setfill('0') << i;
For example, given i as 123, the result is "00123".
However, for the name, which is actually a mixture of a char-string and an integer, I can't figure how to replicate what sprintf appears to do so easily.
I tried variations of this:
ostr << setw(len) << left << "Customer # " << i << setfill(' ');
Given the same value for i, the result was always "Customer # 123", i.e., the integer always right justified, no matter what combination of left, right or internal, or the placement of the various parts. It seems the only solution (I haven't tried it yet), is to first concatenate the "Customer # " and the i onto a separate ostringstream and then insert that left justified to the ostr variable. Am I missing something? Is there some other way?
Correction: as discussed in the comments, in simplifying the example I overlooked a second sprintf that was actually responsible for right-padding the name. So a second output to the ostringsteam is also needed to accomplish that.

How to remove extra space created when using setw in C++?

I am attempting format the output of a file using setw with no success. I understand that my output is shifting based on the character length of the variable before it, however I do not know how to change my code so that each row will print independent of the row before it. (Please see image link)
Due to the word "Swimming" being longer than all other word types, this shifts the information for those columns, making the report look terrible. Additionally, it seems like the comma in the "Amount" Column is shifting the output as well.
fout << s.getID()
<< right << setw(11) << addCommas(s.getAmount()) << "\t"
<< left << setw(14) << s.getType() << "\t"
<< left << setw(14) << s.getLength() << "\t"
<< left << setw(10) << s.getDate() << " "
<< left << setw(15) << s.getFname() << "\t"
<< s.getLname() << endl;
lineCount++;
Current Program Output
(Currently messing with those setw values so please disregard that they don't line up with the header at the moment)
EDIT: Changed my font in VS to Helvetica because Consolas hurts my eyes, this also affected the output of my .dat, so essentially this was a non-issue. Yikes.
If you add std::internal to your std::cout statement, it'll pump the remaining spaces out, and you can do a new setw after that. This might work better than tabs for you, especially if you're not using a monospaced font. See an example in this answer. Make sure your setw is large enough to accommodate your largest words... and don't do using namespace std, it's poor practice. Shame on you! ;)

Is cout.put() recommended over cout<< for printing characters

Background
IIRC, from Release 2.0 C++ stores single-character constants as type char and NOT int. But before Release 2.0 a statement like
cout<<'A'
was problematic as it displays the ASCII value of 'A' ie 65 whereas:
char ch='A';
cout<<ch;
would display the right value ie 'A'.
Since the problem has been rectified in Release 2.0. I believe cout.put() lost the advantage it had over cout<<.
Question
Is there any other reason for recommending cout.put() over cout<< for printing characters?
There are a few differences between cout<< and cout.put, or should we say the overloaded << operator and the put method from std::basic_ostream because this is not really limited to the global instance: cout.
The << operator writes formatted output, the put method does not.
The << operator sets the failbit if the output fails, the put method does not.
Personally I would go with the << operator in almost all cases, unless I had specific needs to bypass the formatted output or not setting the failbit on error.
Using them can result in the following differences of output:
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
cout << "Character: '" << setw(10) << 'A' << setw(0) << "'" << endl;
cout << "Character: '" << setw(10);
cout.put('A');
cout << setw(0) << "'" << endl;
return 0;
}
Outputs:
Character: ' A'
Character: 'A'
See the above in action: http://ideone.com/9N0VYn
Since the put method is unformatted it does not respect the manipulator set, there might be situations where that is indeed what you intend. But since it sounds like you only want to print out the character, I would prefer the << operator, which respects the formatting.
And then there is the case of the failbit which is not being set, and that might even be more crucial.

Right Justifying output stream in C++

I'm working in C++. I'm given a 10 digit string (char array) that may or may not have 3 dashes in it (making it up to 13 characters). Is there a built in way with the stream to right justify it?
How would I go about printing to the stream right justified? Is there a built in function/way to do this, or do I need to pad 3 spaces into the beginning of the character array?
I'm dealing with ostream to be specific, not sure if that matters.
You need to use std::setw in conjunction with std::right.
#include <iostream>
#include <iomanip>
int main(void)
{
std::cout << std::right << std::setw(13) << "foobar" << std::endl;
return 0;
}
Yes. You can use setw() to set the width. The default justification is right-justified, and the default padding is space, so this will add spaces to the left.
stream << setw(13) << yourString
See: setw(). You'll need to include <iomanip>.
See "setw" and "right" in your favorite C++ (iostream) reference for further details:
cout << setw(13) << right << your_string;
Not a unique answer, but an additional "gotcha" that I discovered and is too long for a comment...
All the formatting stuff is only applied once to yourString. Anything additional, like << yourString2 doesn't abide by the same formatting rules. For instance if I want to right-justify two strings and pad 24 asterisks (easier to see) to the left, this doesn't work:
std::ostringstream oss;
std::string h = "hello ";
std::string t = "there";
oss << std::right << std::setw(24) << h << t;
std::cout << oss.str() << std::endl;
// this outputs
******************hello there
That will apply the correct padding to "hello " only (that's 18 asterisks, making the entire width including the trailing space 24 long), and then "there" gets tacked on at the end, making the end result longer than I wanted. Instead, I wanted
*************hello there
Not sure if there's another way (you could simply redo the formatting I'm sure), but I found it easiest to simply combine the two strings into one:
std::ostringstream oss;
std::string h = "hello ";
std::string t = "there";
// + concatenates t onto h, creating one string
oss << std::right << std::setw(24) << h + t;
std::cout << oss.str() << std::endl;
// this outputs
*************hello there
The whole output is 24 long like I wanted.
Demonstration