Shinji-san
Shinji-san

Reputation: 1001

C++'s cin.width function explanation

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

Answers (4)

4386427
4386427

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

Sergey Kalinichenko
Sergey Kalinichenko

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
  • a delimiter character is reached - in your case, whitespace is the delimiter
  • End of input is reached - There's nothing >> can do when there's no more data to read.

Therefore, your loop partitions the input as follows:

  • If a word is shorter than four characters in length, it would be read in its entirety
  • Otherwise, the word would be read in four-character increments; the last part may have fewer than four characters.

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

Dietmar K&#252;hl
Dietmar K&#252;hl

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

R Sahu
R Sahu

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

Related Questions