4

I made a program using structure and pointer. But for some reason it is not working properly. The main problem is that, for-loop would no go as it would. It would be helpful if you could solve this problem

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct Book{
    string name;
    int release;
};

int main(){
    //local variable
    int i;
    string release_dte;
    int choice;
    //interface
    cout << "Welcome to Book Storage CPP" << endl;
    cout << "How many entries would you like to make: ";
    cin >> choice;
    Book* Issue = new Book[choice];
    //for handler
    for (i = 0; i < choice; i++){
        cout << "Book: ";
        getline(cin, Issue[i].name);
        cout << "Release Date: ";
        getline(cin, release_dte);
        Issue[i].release = atoi(release_dte.c_str());
    }
    cout << "These are your books" << endl;
    for ( i = 0; i < choice; i++){
        cout << "Book: " << Issue[i].name << " Release Date: " << Issue[i].release << endl;
    }
    system("pause");
    return 0;
} 
5
  • What exactly fails? What do you see, what do you expect? Compile the program with all warnings (and optimization, the compiler might notice some problems only while doing the analysis for optimization). There just isn't a way around you learning to find out what goes on here. Commented Feb 3, 2014 at 1:24
  • Basically, when this program get to for-loop. It skips over the first input and goes to the second one. Commented Feb 3, 2014 at 1:25
  • That's because you still have a newline stuck in the beginning of the stream. std::getline() stops when it hits a newline, that's why the input isn't being attempted. Commented Feb 3, 2014 at 1:39
  • @user3264250, see my answer down, you have to add a cin.ignore() to avoid the new line issue between the two getline() functions Commented Feb 3, 2014 at 1:44
  • @0x499602D2 if you don't mind, can you tell me in detail of what you are trying to say. Commented Feb 3, 2014 at 4:16

2 Answers 2

2

You're not checking if the input succeeded, nor are you clearing the new line left after the extraction into choice:

if ((std::cout << "Book: "),
        std::getline(std::cin >> std::ws, Input[i].name) &&
    (std::cout << "Release Date: "),
        std::getline(std::cin >> std::ws, release_dte))
{
    Input[i].release = std::stoi(release_dte);
}

You should also be using std::stoi for C++ strings as shown above.

Sign up to request clarification or add additional context in comments.

7 Comments

Note that std::stoi is only available since C++11.
Just few question I would like you to answer since I am just a beginner 1)Why would you put if statement 2) what does std::ws means 3)Can you kindly explain me what is happening here, in easy terms would be nice
@user3264250 1) std::getline() returns std::cin. When we put it in the context of an if statement, it will return true if the extraction was succesful, or false if the extraction failed. 2) std::ws is a manipulator that extracts and discards leading whitespace from the stream. Whitespace is considered by the stream to be the space character, the newline character, and some others. It will stop when it reaches the end of the stream or when it finds a non-whitespace character. I will answer question 3 in my next comment...
@user3264250 3) When you did cin >> choice, you entered the number and you also pressed Enter which left the newline character in the stream. std::getline() stops extracting input when it finds a newline character. If the first character is a newline, the input cannot be performed. That's why you are experiencing that "skipping" behavior. The second call to std::getline() works because when std::getline() discovers a newline character, it stops the input and then discards the newline character. That's why you have to discard the leading whitespace before std::getline() begins.
@user3264250 If you have any more questions or concerns, just ask here and I will try my best to explain it to you.
|
2

I could not exactly infer what is the problem you are referring to. But my guess is getline() function inside the for loop is not working properly, I suggest the code before the for loop to be like the following\

cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');

for (i = 0; i < choice; i++){
    cout << "Book: ";
    getline(cin, Issue[i].name);
    cout << "Release Date: ";
    getline(cin, release_dte);
    Issue[i].release = atoi(release_dte.c_str());
}

Your final code should be

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

struct Book{
  string name;
  int release;
};

int main(){
//local variable
int i;
string release_dte;
int choice;
//interface
cout << "Welcome to Book Storage CPP" << endl;
cout << "How many entries would you like to make: ";
cin >> choice;
Book* Issue = new Book[choice];

cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n');

//for handler
for (i = 0; i < choice; i++){
    cout << "Book: ";
    getline(cin, Issue[i].name);
    cout << "Release Date: ";
    getline(cin, release_dte);
    Issue[i].release = atoi(release_dte.c_str());
}
cout << "These are your books" << endl;
for ( i = 0; i < choice; i++){
    cout << "Book: " << Issue[i].name << " Release Date: " << Issue[i].release << endl;
}
system("pause");
return 0;

}

This will work as you intended

4 Comments

Well it did gave me the chance to input but when it come to display, It displays everything but not the first book input as in Welcome to Book Storage cpp How many entries would you like to make: 1 Book: Blah Release Date: 1999 Book: Release Date:1999
add this cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n'); before the for loop as well, then it works fine
Well I did like your method and worked fine but there is a huge gap between Book and Release Date. Why is that?
actually this line cin.ignore (std::numeric_limits<std::streamsize>::max(), '\n'); should come before the for loop not inside the loop, then it works fine, i have edited my answer, see that

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.