std::cin to a text file

I am trying to put some data into a text file, and the std::cin.failbit() is always triggered after the sting input?
Can anyone help please!!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 
#include <iostream>
#include <ostream>
#include <istream>
#include <fstream>
#include <string>

int main(int argc, const char * argv[]) {
    
    std::string accountName;
    int accountNumber;
    float accountBalance;
    
    std::string path = "/Users/james/Documents/C++/";
    std::string filename;
    std::string pathAndFilename;
    
    std::cout << "Input filename to work with: ";
    std::cin >> filename;
    
    pathAndFilename = path + filename;
    
    
    
    
    std::fstream inOldMaster;
    inOldMaster.open( pathAndFilename, std::ios::in | std::ios::out | std::ios::app );
    
    
    
   
    if (!inOldMaster ) {
        std::cerr << "File could not be opened" << std::endl;
        exit( 1 );
    }//end if
    
    std::cout << "Enter the account, name, and balance." << "\nEnter end-of-file to end input.\n? ";
    
    // read account, name and balance from cin, then place in file
    while ( std::cin  ) {
        
        std::cin >> accountNumber;
        std::cin >> accountName;
        std::cin >> accountBalance;
        
        inOldMaster << accountNumber << ' ' << accountName << ' ' << accountBalance << std::endl;
        std::cout << "? ";
    } // end while
    
    inOldMaster.close();
    
    
    
    
    
    return 0;
}


What exactly are you trying to input?

Don't forget that the extraction operator will stop processing string input when it encounters a whitespace character.



i am trying to input an int for the accountnumber , string for the account name and float for account balance.
The following works:-
100 James 345

Whereas this doesn't
100 John Doe 234

The std::cin failbit is set.
That would be correct. Read the last sentence of my last post. You can't use the extraction operator if your string has whitespace characters. You will probably want to use getline(), but be aware if the user enters data like:

100
James
345

100
John Doe
234

You may have problems when switching between the extraction operator and getline() because the extraction operator will leave the new line character in the input buffer, that you'll need to extract.

Something like:

1
2
3
        std::cin >> accountNumber;
        getline(std::cin >> std::ws, accountName); // Consume any leading ws.
        std::cin >> accountBalance;


Last edited on
Thanks! The input needs to be in the form

100 John Doe 234

ive tried std::getline ( std::cin, accountName )

but the program hangs.

ive tried std::cin.ignore( cin.rdbuf()->in_avail() );

still can't get it to work as i Want!!
The input needs to be in the form

100 John Doe 234


If you need to enter all the data on a single line, then the getline() will receive "John Doe 234" which is almost certainly not what you want.

If the input was in this form, things would be easier:
100
John Doe
234

Something like this could work:
1
2
3
4
5
6
7
8
9
    // read account, name and balance from cin, then place in file
    while (  std::cin >> accountNumber >> std::ws
          && getline(std::cin,accountName)
          && std::cin >> accountBalance  )
    {
        
        inOldMaster << accountNumber << ' ' << accountName << ' ' << accountBalance << '\n';
        std::cout << "? ";
    }

Above, I've used a variation of the std::ws suggested by jlb previously.

ive tried std::cin.ignore( cin.rdbuf()->in_avail() );

This looks good, unfortunately the standard doesn't guarantee that in_avail() will do anything useful.

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


More than you ever wanted to know:
https://www.daniweb.com/programming/software-development/threads/90228/flushing-the-input-stream
it might be better to set up a struct/class capturing the Number, Name, Balance data-members, overload the ctor to create an instance of this type with input data and overload the stream insertion operator << to send the object to a file
Ive had a bit of a re-hash and it seems to be doing what I want now...
Any thoughts on improvement!

Thanks for your help!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98

#include <iostream>
#include <ostream>
#include <istream>
#include <fstream>
#include <string>
#include <sstream>

int getAccountNumber();
std::string getAccoutName();
float getAccountBalance();

int main(int argc, const char * argv[]) {
    
    
    
    std::string path = "/Users/james/Documents/C++/";
    std::string filename;
    std::string pathAndFilename;
    
    std::cout << "Input filename to work with: ";
    std::cin >> filename;
    
    pathAndFilename = path + filename;
    
    
    
    
    std::fstream inOldMaster;
    inOldMaster.open( pathAndFilename, std::ios::in | std::ios::out | std::ios::app );
    
    if (!inOldMaster ) {
        std::cerr << "File could not be opened" << std::endl;
        exit( 1 );
    }//end if
    
    char sentinel = 'y';
    
    do{
        std::cout << "Input as directed" << std::endl;
        inOldMaster << getAccountNumber() << ' ' << getAccoutName() << ' ' << getAccountBalance() <<  std::endl;
        std::cout << "Input again Y/N ? ";
        std::cin >> sentinel;
      while( (sentinel != 'n' && sentinel != 'N') && (sentinel != 'Y' && sentinel != 'Y' )) {
          std::cin.clear();
          std::cin.ignore();
          std::cout << "Input (inner while) again Y/N ? ";
          std::cin >> sentinel;
          std::cout << sentinel << std::endl;
      }//end inner while
    }while( (sentinel == 'y' || sentinel == 'Y') );
    
    inOldMaster.close();
        
    return 0;
}


int getAccountNumber(){
    
    int number;
    std::cout << "Input account number:- ";
    std::cin >> number;
    while( !std::cin ) {
        std::cin.clear();
        std::cin.ignore();
        std::cout << "Input account number:- ";
        std::cin >> number;
    }
    
    return number;
}


std::string getAccoutName(){
    
    std::string name;
    std::cout << "Input account name:- ";
    std::getline( std::cin >> std::ws, name );
    return name;
}


float getAccountBalance(){
    float balance;
    
    std::cout << "Input account balance:- ";
    std::cin >> balance;
    while( !std::cin ) {
        std::cin.clear();
        std::cin.ignore();
        std::cout << "Input account balance:- ";
        std::cin >> balance;
    }
    
    return balance;
}
Topic archived. No new replies allowed.