Reputation: 1001
I've read this passage in the book(which barely explained) a dozen times but can't understand how this is really working. I'm trying to figure out how the functions are working.
int main() {
int widthValue = 4;
char sentence[ 10 ];
cout << "Enter a sentence:" << endl;
cin.width( 5 ); // input only 4 characters from sentence
// set field width, then display characters based on that width
while ( cin >> sentence )
{
cout.width( widthValue++ );
cout << sentence << endl;
cin.width(5); // input 5 more characters from sentence
} // end while
return 0;
} // end main
Now the following output is produced, and here's my trouble. The first line says cin.width, and this line means that the first 4 characters, actually, will be read - namely, "This", but then you output a field width of 4, so when you execute the 'cout << sentence << endl statement you print 4 characters, namely - "This". After, you read 5 more characters from sentence. But I get lost on the next iteration of the loop because the width then becomes 5, yet you output " is". I don't get the concept.
Upvotes: 4
Views: 4793
Reputation: 44329
Whenever you do a new cin >> sentence
it overwrites whatever was in sentence
before. Also the input stops at a space. Consequently the second loop will just give you is
Upvotes: 1
Reputation: 726809
When you set width(w)
on cin
and then read a C string from it, operator >>
stops when one of the following happens:
w-1
characters have been read - >>
needs one more character for null terminator, which is included in the count>>
can do when there's no more data to read.Therefore, your loop partitions the input as follows:
Printing is right-justified, with spaces pre-pended to each word or a portion of the word that was previously read from cin
. The widthValue++
expression controls the overall width, so each next word gets one extra space in front of it.
Here is the output for "jackdaws love my big sphinx of quartz"
, with |
marks added to show the beginning and the end of each line:
|jack|
| daws|
| love|
| my|
| big|
| sphi|
| nx|
| of|
| quar|
| tz|
Upvotes: 3
Reputation: 153955
When you use formatted input with a char*
the stream's width()
determines the maximum number of character which fit into the corresponding array. Since the stream need to be null terminated, at most s.width() - 1
will be read to allow for storing the terminating null character.
The formatted input also starts with skipping leading whitespace and stops upon reaching the first whitespace. That is, input stopes when either width()-1
character have been stored or a space is reached. Once the input is done, the current width()
is reset to 0
(the width()
is the only formatting flag which keeps getting reset; all other formatting flags keep their value until a new one is set).
For output, the width()
specifies the number of characters which should be printed. If the value to be printed doesn't produce enough character, the remaining characters are padded, i.e., the current fill character (accessed with the fill()
members) is used to write, at least, width()
characters. Again, the width()
gets reset to 0
after use.
The width()
for input and output have entirely different purposes. Probably, different members should be used. In particular, formatted input into a char
array is the only use of width()
for input in the standard C++ library.
Upvotes: 1
Reputation: 206667
From http://en.cppreference.com/w/cpp/io/basic_istream/operator_gtgt2:
The extraction stops if one of the following conditions are met:
- a whitespace character (as determined by the ctype facet) is found. The whitespace character is not extracted.
- st.width() - 1 characters are extracted
- end of file occurs in the input sequence (this also sets eofbit)
Hence, if your input is:
This is a line line.
the contents of sentence
will be "is"
in the second iteration of the loop.
Upvotes: 1