How does std::setw work with string output? - c++

I am trying to use set width setw for string output to an output file, however, I am not able to make it work. I have with me the following example.
// setw example
#include <iostream>
#include <iomanip>
#include <fstream>
int main () {
std::ofstream output_file;
output_file.open("file.txt");
output_file << "first" <<std::setw(5)<< "second"<< std::endl;
output_file.close();
return 0;
}
Edit:
With the above lines I expected to have many spaces between first and second, something like
first second
I hardly see any spaces, the output just comes like firstsecond
I think I missed the working of setw()
Note: For integers, it works fine just:
output_file << 1 <<std::setw(5)<< 2 << std::endl;
What I am doing wrong??.

I suspect your understanding of std::setw is simply not correct. I think you need something more along the lines of a combination of:
std::setw for setting field width
std::setfill for setting the fill character
std::left, std::right, std::internal for setting the write position within the specified field width.
What is happening in your code:
Uses std::setw(5) to establish a field width of five characters.
Sends "first" to the stream, which is five characters long, so the established field width is completely consumed. No additional filling takes place.
Sends "second" to the stream, which is six characters long, so again, the entire field width is consumed (and in-fact breached). Again, no filling takes place
If you're intent is to have something like this (with column numbers above to show positions):
col: 0123456789012345678901234567890123456789
first second third fourth
Notice how each word starts on an even multiple of 10 boundary. One way to do that is by using :
A output position std::left (so the fill, if any goes on the right to achieve the desired width). This the default for strings, but it never hurts to be sure.
A fill character of std::setfill(' '). Again, the default.
A field width std::setw(10) Why such a large number? See below
Example
#include <iostream>
#include <iomanip>
int main ()
{
std::cout << std::left << std::setfill(' ')
<< std::setw(10) << "first"
<< std::setw(10) << "second"
<< std::setw(10) << "third"
<< std::setw(10) << "fourth" << '\n';
return 0;
}
Output (column numbers added)
0123456789012345678901234567890123456789
first second third fourth
So what happens if we change the output location to std::right ? Well, with the identical program, changing only the first line to :
std::cout << std::right << std::setfill(' ')
we get
0123456789012345678901234567890123456789
first second third fourth
Finally, one constructive way of seeing where the fill characters are being applied is by simply changing the fill char to something visible (ie. something besides a space). The last two examples output, changing the fill char to std::setfill('*') produces the following output:
First
first*****second****third*****fourth****
Second
*****first****second*****third****fourth
Notice in both cases, since none of the individual output items breached the std::setw value, the total output line size for each is the same. All that changed was where the fills were applied and the output aligned within the std::setw specification.

Related

String stream output compare

I want to compare output of stringstream with some string.
Problem is when I use fill and width on stringstream I cant compare resulting string with preloaded string.
std::stringstream sstr;
sstr.fill(' ');
sstr.width(4);
sstr << 4 << std::endl;
if(" 4" == sstr.str()){
std::cout << "Equal" << std::endl;
}
It's not equal. My educated guess would be that width somehow use some kind of flag or other kind of indicator to replace bunch of spaces in string. But I am not sure and didn't find anything useful on google. Does anyone know why I cannot compare that (sstream.str() and targeted string)?
Goal is to test what will stringstream (which is heart of my component) print on console.
You also inserted a std::endl into the string. That's going to add a newline character to the string.
Remove the std::endl from your output.

Most efficient way to output a newline

I was wondering what is the most efficient performant way to output a new line to console. Please explain why one technique is more efficient. Efficient in terms of performance.
For example:
cout << endl;
cout << "\n";
puts("");
printf("\n");
The motivation for this question is that I find my self writing loops with outputs and I need to output a new line after all iterations of the loop. I'm trying to find out what's the most efficient way to do this assuming nothing else matters. This assumption that nothing else matters is probably wrong.
putchar('\n') is the most simple and probably fastest. cout and printf with string "\n" work with null terminated string and this is slower because you process 2 bytes (0A 00). By the way, carriage return is \r = 13 (0x0D). \n code is Line Feed (LF).
You don't specify whether you are demanding that the update to the screen is immediate or deferred until the next flush. Therefore:
if you're using iostream io:
cout.put('\n');
if you're using stdio io:
std::putchar('\n');
The answer to this question is really "it depends".
In isolation - if all you're measuring is the performance of writing a '\n' character to the standard output device, not tweaking the device, not changing what buffering occurs - then it will be hard to beat options like
putchar('\n');
fputchar('\n', stdout);
std::cout.put('\n');
The problem is that this doesn't achieve much - all it does (assuming the output is to a screen or visible application window) is move the cursor down the screen, and move previous output up. Not exactly a entertaining or otherwise valuable experience for a user of your program. So you won't do this in isolation.
But what comes into play to affect performance (however you measure that) if we don't output newlines in isolation? Let's see;
Output of stdout (or std::cout) is buffered by default. For the output to be visible, options include turning off buffering or for the code to periodically flush the buffer. It is also possible to use stderr (or std::cerr) since that is not buffered by default - assuming stderr is also directed to the console, and output to it has the same performance characteristics as stdout.
stdout and std::cout are formally synchronised by default (e.g. look up std::ios_base::sync_with_stdio) to allow mixing of output to stdout and std::cout (same goes for stderr and std::cerr)
If your code outputs more than a set of newline characters, there is the processing (accessing or reading data that the output is based on, by whatever means) to produce those other outputs, the handling of those by output functions, etc.
There are different measures of performance, and therefore different means of improving efficiency based on each one. For example, there might be CPU cycles, total time for output to appear on the console, memory usage, etc etc
The console might be a physical screen, it might be a window created by the application (e.g. hosted in X, windows). Performance will be affected by choice of hardware, implementation of windowing/GUI subsystems, the operating system, etc etc.
The above is just a selection, but there are numerous factors that determine what might be considered more or less performance.
On Ubuntu 15.10, g++ v5.2.1 (and an older vxWorks, and OSE)
It is easy to demonstrate that
std::cout << std::endl;
puts a new line char into the output buffer, and then flushes the buffer to the device.
But
std::cout << "\n";
puts a new line char into the output buffer, and does not output to the device. Some future action will be needed to trigger the output of the newline char in the buffer to the device.
Two such actions are:
std::cout << std::flush; // will output the buffer'd new line char
std::cout << std::endl; // will output 2 new line chars
There are also several other actions that can trigger the flush of the std::cout buffering.
#include <unistd.h> // for Linux
void msDelay (int ms) { usleep(ms * 1000); }
int main(int, char**)
{
std::cout << "with endl and no delay " << std::endl;
std::cout << "with newline and 3 sec delay " << std::flush << "\n";
msDelay(3000);
std::cout << std::endl << " 2 newlines";
return(0);
}
And, per comment by someone who knows (sorry, I don't know how to copy his name here), there are exceptions for some environments.
It's actually OS/Compiler implementation dependent.
The most efficient, least side effect guaranteed way to output a '\n' newline character is to use std::ostream::write() (and for some systems requires std::ostream was opened in std::ios_base::binary mode):
static const char newline = '\n';
std::cout.write(&newline,sizeof(newline));
I would suggest to use:
std::cout << '\n'; /* Use std::ios_base::sync_with_stdio(false) if applicable */
or
fputc('\n', stdout);
And turn the optimization on and let the compiler decide what is best way to do this trivial job.
Well if you want to change the line I'd like to add the simplest and the most common way which is using (endl), which has the added perk of flushing the stream, unlike cout << '\n'; on its own.
Example:
cout << "So i want a new line" << endl;
cout << "Here is your new line";
Output:
So i want a new line
Here is your new line
This can be done for as much new lines you want. Allow me to show an example using 2 new lines, it'll definitely clear all of your doubts,
Example:
cout << "This is the first line" << endl;
cout << "This is the second line" << endl;
cout << "This is the third line";
Output:
This is the first line
This is the second line
This is the third line
The last line will just have a semicolon to close since no newline is needed. (endl) is also chain-able if needed, as an example, cout << endl << endl; would be a valid sequence.

How can I make the sign appear at the end of the fill when using std::cout and std::stringstream?

I have the following code for formatting a printout to always be 4 digits with sign included:
std::stringstream pitch;
pitch.precision(0);
pitch.width(4);
pitch.fill('0');
pitch << std::showpos << (int)(m_values["Pitch_1"]);
I would also like to show the sign ("+"/"-"), but I want it to precede the fill, as follows:
+002
However, the code I have here moves the "+" sign to the most significant digit:
00+2
How, if possible, can I change the formatting so that I have the former, instead of the latter?
Use the std::internal manipulator:
pitch << std::internal << std::showpos << 5;

Space vs null character

In C++, when we need to print a single space, we may do the following:
cout << ' ';
Or we can even use a converted ASCII code for space:
cout << static_cast<char>(32); //ASCII code 32 maps to a single space
I realized that, printing a null character will also cause a single space to be printed.
cout << static_cast<char>(0); //ASCII code 0 maps to a null character
So my question is: Is it universal to all C++ compilers that when I print static_cast<char>(0), it will always appear as a single space in the display?
If it is universal, does it applies to text files when I use file output stream?
No, it will be a zero(0) character in every compiler. Seems that the font you use renders zero characters as a space. For example, in the old times, DOS had a different image (an almost filled rectangle) for zero characters.
Anyway, you really should not output zero characters instead of spaces!
As for the text file part: open the outputted file using a hex editor to see the actual bits written. You will see the difference there!
On my computer, this code
#include <iostream>
int main() {
std::cout << "Hello" << static_cast<char>(0) << "world\n";
}
outputs this:
Helloworld
So no, it clearly doesn’t work.

What does the combination of setf(ios::left, ios::adjustfield) do?

I was reading a textbook and I came across this line.
It seems to format output prettily in two columns (I'm guessing the left one get set width making the right one look even since it all starts at the same column). I'm not too sure about what the line is really doing though.
cout.setf(ios::left, ios::adjustfield);
Can someone explain this to me?
It forces text in a fixed width field to be output with left justification. See this reference. This is using the second override of that function that takes in the mask in which to set the particular flags.
This override will clear any existing flags that are set in std::ios_base::adjustfield, which handles justification of text output through a stream object.
The override that doesn't take the flag mask (second parameter) will simply additionally set the flag specified, which doesn't make a lot of sense in the case of adjustfield since the valid values are only left, right, and internal, which all deal with text justification.
Hopefully this small example will make it clear:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout.setf(std::ios::left, std::ios::adjustfield);
cout << setfill('^') << setw(10) << "Hello" << "\n";
cout.setf(std::ios::right, std::ios::adjustfield);
cout << setfill('0') << setw(10) << "99\n";
return 0;
}
It gives the output:
Hello^^^^^
000000099