0

I was learning about the concepts of pointers and just as I thought I got my concepts , this program caused me trouble understanding how the inputs of different datatype are being stored in a program..

And then I learnt about cin.ignore() and tested it out..

Inputs

32 // int
64.212 // float
4.76545 // double
* // char
Hey look at me! I know pointers! // string

First Program without cin.ignore():

#include<iostream>
#include<string>

using namespace std;
int main()
{
    int givenInt;
    float givenFloat;
    double givenDouble ;
    std::string givenString;
    char givenChar;

    cin>>givenInt;
    cin>>givenFloat;
    cin>>givenDouble;
    cin>>givenChar;
    getline(cin,givenString);

    cout<<"givenInt = "<<givenInt<<'\n';
    cout<<"address of givenInt = "<<&givenInt<<'\n';

    cout<<"givenFloat = "<<givenFloat<<'\n';
    cout<<"address of givenFloat = "<<&givenFloat<<'\n';

    cout<<"givenDouble = "<<givenDouble<<'\n';
    cout<<"address of givenDouble = "<<&givenDouble<<'\n';

    cout<<"givenChar = "<<givenChar<<'\n';
    cout<<"address of givenChar = "<<(void*)&givenChar<<'\n';

    cout<<"givenString = "<<givenString<<'\n';
    cout<<"address of givenString = "<<&givenString<<'\n';

    return 0;
} 

Output :

givenInt = 32
address of givenInt = 0x7ffd62e17cd8
givenFloat = 64.212
address of givenFloat = 0x7ffd62e17cdc
givenChar = *
address of givenChar = 0x7ffd62e17cd7
givenString = 
address of givenString = 0x7ffd62e17ce0
givenDouble = 4.76545
address of givenDouble = 0x7ffd62e17ce8

Input string does not appear on output..

First Program with cin.ignore():

#include<iostream>
#include<string>

using namespace std;
int main()
{
    int givenInt;
    float givenFloat;
    double givenDouble ;
    std::string givenString;
    char givenChar;

    cin>>givenInt;
    cin>>givenFloat;
    cin>>givenDouble;
    cin.ignore();
    cin>>givenChar;
    cin.ignore();
    getline(cin,givenString);

    cout<<"givenInt = "<<givenInt<<'\n';
    cout<<"address of givenInt = "<<&givenInt<<'\n';

    cout<<"givenFloat = "<<givenFloat<<'\n';
    cout<<"address of givenFloat = "<<&givenFloat<<'\n';

    cout<<"givenDouble = "<<givenDouble<<'\n';
    cout<<"address of givenDouble = "<<&givenDouble<<'\n';

    cout<<"givenString = "<<givenString<<'\n';
    cout<<"address of givenString = "<<&givenString<<'\n';

    cout<<"givenChar = "<<givenChar<<'\n';
    cout<<"address of givenChar = "<<(void*)&givenChar<<'\n';

    return 0;
}

Output :

givenInt = 32
address of givenInt = 0x7ffcf69bd9a8
givenFloat = 64.212
address of givenFloat = 0x7ffcf69bd9ac
givenChar = *
address of givenChar = 0x7ffcf69bd9a7
givenString = Hey look at me! I know pointers!
address of givenString = 0x7ffcf69bd9b0
givenDouble = 4.76545
address of givenDouble = 0x7ffcf69bd9b8

Input Strings appear on the output..

Second Program with cin.ignore():

#include<iostream>
#include<string>

using namespace std;
int main()
{
    int givenInt;
    float givenFloat;
    double givenDouble ;
    std::string givenString;
    char givenChar;

    cin>>givenInt;
    cin>>givenFloat;
    cin>>givenDouble;
    cin.ignore();
    getline(cin,givenString);
    cin.ignore();
    cin>>givenChar;
    cin.ignore();

    cout<<"givenInt = "<<givenInt<<'\n';
    cout<<"address of givenInt = "<<&givenInt<<'\n';

    cout<<"givenFloat = "<<givenFloat<<'\n';
    cout<<"address of givenFloat = "<<&givenFloat<<'\n';

    cout<<"givenDouble = "<<givenDouble<<'\n';
    cout<<"address of givenDouble = "<<&givenDouble<<'\n';

    cout<<"givenString = "<<givenString<<'\n';
    cout<<"address of givenString = "<<&givenString<<'\n';

    cout<<"givenChar = "<<givenChar<<'\n';
    cout<<"address of givenChar = "<<(void*)&givenChar<<'\n';

    return 0;
}

Output

givenInt = 32
address of givenInt = 0x7ffe1ed66698
givenFloat = 64.212
address of givenFloat = 0x7ffe1ed6669c
givenChar = e
address of givenChar = 0x7ffe1ed66697
givenString = *
address of givenString = 0x7ffe1ed666a0
givenDouble = 4.76545
address of givenDouble = 0x7ffe1ed666a8 

Input character goes to the string variable and string's second letter gets printed on character variable..

I thought that since double uses buffer to store characters (If I am wrong, please correct me), let me use it at last since it does not affect the inputs which are taken after double. But I was wrong and it gave me similar kind of result as the first program. And after testing out both programs with and without using cin.ignore(), I got to know that we need to use cin.ignore() whenever I take inputs of double and strings datatype.

My questions are,

1) Is my concept of "using cin.ignore() when taking inputs of double and string datatype" correct? Should I take the inputs in a particular order only?

2) Why is (void*) used along with &givenChar only for getting the address of a character type? &givenChar should do the job right?

  • This question has a really in-depth explanation for your first question [Why does std::getline skip input after a formatted extraction](https://stackoverflow.com/questions/21567291/why-does-stdgetline-skip-input-after-a-formatted-extraction) – nick Mar 29 '20 at 03:27
  • If you expect to read a line of input, this is what `std::getline` is for. No need to mess around with `ignore`, or anything like that. If the line of input is expected to be a numerical type, this is what `std::istringstream` is for. Take the resulting string, convert it to a `std::istringstream`, and use `>>` to parse it. But `>>` alone is not, I repeat, ***is not*** for reading a line of input, and all those contortions involving `ignore` is just a symptom of using the wrong tool for the wrong job. – Sam Varshavchik Mar 29 '20 at 03:32
  • So, if I take scanf instead of cin, scanf does a better job than cin, am I right? – Sourabh Misal Mar 29 '20 at 03:41

1 Answers1

0
  1. When you use cin >> ... the stream trims any and all whitespace from the beginning of the input and begins to parse the rest characters into the object. It stops when it finds whitespace or a newline. It won't skip the whitespace at the end but just leave it in the stream. getline does slightly the same except it doesn't trim whitespace at the beginning. It reads until it finds a newline, discards that newline, and stops. So if you have a getline() call after a >>, then you need to manually remove the extra whitespace at the beginning. That's what ignore() is for. It just skips a single character.

  2. &givenChar has the type char*. The type of std::cout, std::ostream, has several overloads of the << operator. One of them takes the type char* and treats it as a string. It attempts to iterate over the string until it finds a null terminator. In this case &givenChar is a pointer to a single character, not a pointer to the beginning of a character array. In order to select the correct overload a cast to (void*) is needed. The << operator for void* displays the address.

0x499602D2
  • 87,005
  • 36
  • 149
  • 233
  • So, after the double variable gets filled, there are white space remaining, so ```ignore()``` removes those whitespace in the stream and for the next variable, input gets stored properly, am I right? – Sourabh Misal Mar 29 '20 at 03:46