cin buffer errors

this is not working i do not know why. here are the files.
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
//
//  main.cpp
//  dealer2
//
//  Created by Home on 4/23/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#include <iostream>
#include "Header.h"
#include <fstream>
#include <exception>
#include <string> 
#include <stdio.h>
#include <stdlib.h>

#define STRAIGHT_FLUSH 6
#define FLUSH 5
#define FOUR_OF_A_KIND 4
#define STRAIGHT 3
#define THREE_OF_A_KIND 2
#define PAIR 1
#define EMPTY 0 

void wait(int); 
void newshift(aCard,int,DeckofCards&);  
bool sortorder(const aCard&,const aCard&); 
void swap(aCard&,aCard &); 
void sort(aCard[]);   
int quat();
void replace(aCard[],DeckofCards&); 
int determinate(aCard[]); 
std::string won(int);

aCard operator+(aCard a, int i){//not sure if i need this
    aCard temp;
    temp.suit = a.suit; 
    temp.value = a.value + i; 
    return temp; 
}

bool operator==(aCard a, aCard b){
    if((a.value == b.value) && (a.suit == b.suit)) return true; 
    else return false; 
}

int main(){
    int wager = 0; 
    int bank = quat();
    
    if(bank == EXIT_FAILURE){ bank = 100; 
        std::cout << "\nNo bank was found. Starting with " << bank << " Quatloos\n";
    }
    else{
        std::cout << "Your accout has " << bank << " Quatloos\n"; 
    }
    
    DeckofCards deck; deck.shuffle(); aCard hand[5]; 
    
    for(int i = 0; i < 5; i++){hand[i] = deck.deal();}//deal first hand
    sort(hand); //sorts hand
    wait(1);
   
    displayHand(hand, "Your cards so far..."); //displays hand
    
    while(wager > bank || wager == 0){ 
        std::cout << "What is your wager?";
        std::cin >> wager; //get  
        std::cin.clear(); //clear
    }
    bank-= wager; 
    
    replace(hand, deck); //error occurs here
    
    sort(hand); 
    displayHand(hand, "Your Cards"); 
    int profit = determinate(hand) * wager; 
    bank += profit; 
    if(profit == 0) std::cout << "You lost"; 
    else { std::cout << "You Have a " << won(profit/wager) << " And made " << profit << "$"; }

    return EXIT_SUCCESS;
}

std::string won(int i){
    switch (i) {
        case 6:
            return "Straight Flush"; 
            break;
        case 5:
            return "Flush"; 
            break;
        case 4:
            return "Four of a Kind"; 
            break;
        case 3:
            return "Straight"; 
            break;
        case 2:
            return "Three of a kind"; 
            break;
        case 1:
            return "Pair"; 
            break;
            
        default:
            break;
    }
    return NULL; 
    }
    
bool sortorder(const aCard &a, const aCard &b){
    if(a.suit < b.suit) 
        return true; 
    if(a.suit == b.suit){
        if(a.value < b.value)
            return true;
    }
    return false; 
}

int quat(){
    std::ifstream bank; int i; 
    bank.exceptions(std::ifstream::failbit | std::ifstream::badbit); 
    try{bank.open("/Users/home/Desktop/dealer2/dealer2/bank.txt");}
    catch(std::ifstream::failure &e){
        std::cout << "An error has occured: " << e.what(); 
        return EXIT_FAILURE; 
    }
    bank >> i;
    bank.close(); 
    return i; 
}

void wait(int seconds){
    clock_t endwait;
    endwait = clock() + seconds * CLOCKS_PER_SEC; 
    while(clock() < endwait) {} 
}

void swap(aCard &a, aCard &b){
    aCard temp; 
    temp = b; 
    b = a;
    a = temp;
}

void sort(aCard x[]){
    for(int i = 0; i < 5; i++){
        for(int j = 0; j < 5; j++){
            if(sortorder(x[i], x[j])) swap(x[i], x[j]); 
        }
    }
}

void replace(aCard x[], DeckofCards &y){ //error occurs here
    std::string s; 
    std::cout << "      Card 1       Card 2       Card 3       Card 4       Card 5\n"; 
    std::cout << "Which cards would you like to replace: ";
    std::cin.clear(); //clear
    std::cin.sync(); //sync
    if(!std::cin.good()) {std::cout << "CIN ERROR"; //still throws here 
        exit(3);}
    getline(std::cin, s); //this skips before i added 
    for(int i = 0; i < s.length(); i++){
        if(!isspace(s[i])){
            int j = atoi(&s[i]);
            x[--j] = y.deal(); 
        }
    }
}

int determinate(aCard x[]){
    int q = 1; 
    int suit_match = 0, value_match = 0, consecutive_value = 0; 
    for(int i = 0; i < 5; i++){
        for(int j = i+1; j < 5; j++){
            if(x[i].suit == x[j].suit) ++suit_match;
            if(x[i].value == x[j].value) ++value_match; 
            if(x[i] == x[j] + q++) ++consecutive_value;  
        }
        q += 10; 
    }
        if( suit_match == 5 && consecutive_value == 5) return STRAIGHT_FLUSH;
        if( value_match == 4) return FOUR_OF_A_KIND; 
        if( suit_match == 5 ) return FLUSH; 
        if( consecutive_value == 5) return STRAIGHT; 
        if( value_match == 3) return THREE_OF_A_KIND; 
        if( value_match == 2) return PAIR; 
    return EMPTY; 
}
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
#ifndef HEADER_H
#define HEADER_H

struct aCard{
    char suit;     // one of the four suits(H,D,C,S)
    int value;     // ranges from 2..14  An 'ace' is 14
};

void displayHand(aCard[],std::string); // This is the only function you call 
//to display
// a hand of cards

// IGNORE THESE   *******for printing the cards******
void displayRowofValues(aCard[]);
void displayRowofSuits(aCard[]);
void displaySuits(char, int);
void toporBottom();
void edges();
// END IGNORE


class DeckofCards{
public: 
    DeckofCards();              // constructs a deck of cards
    
    void displayDeck();  // displays the deck of cards to cout stream
    
    void shuffle();             // shuffles a deck of cards
    
    bool isEmpty() const;        // returns 0 if no cards remain 
    //  otherwise nonzero
    
    aCard deal();               // returns one card of type aCard
    //  deck is updated to 'remove' this card
private:
    aCard deck_[52];            // deck of cards
    int nextCard_;              // position of next card to be dealt
};
#endif //HEADER_H 
rest of fies:
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
#include <iostream>
#include <iomanip.h>
#include <stdlib.h>
#include <string>
#include "Header.h"


DeckofCards::DeckofCards(){
    nextCard_ = 0;       // next card drawn will be 'top' card in deck
    char suits[4];
    suits[0] = 'C';
    suits[1] = 'D';
    suits[2] = 'H';
    suits[3] = 'S';
    
    int k = 0;
    
    for (int i = 0; i < 4; i++) 
        for (int j = 2; j < 15; j++) {
            deck_ [k].suit = suits[i];
            deck_ [k++].value = j;
        }
    
}      

void DeckofCards::shuffle(){
    if(isEmpty() && nextCard_ ){//correct this... 
        cerr << "shuffle:  Must have full deck to shuffle..." << endl;
        exit(2);
    }
    
    aCard temp[52];
    
    int i;
    int r;
    int seed;
    seed = int(time(NULL));
    srand(seed);
    r = rand()/100%52;
    
    for ( i = 0; i < 52; i++) {
        while (deck_[r].value == 0){
            r = rand()/100%52;
        }
        
        temp[i] = deck_[r];
        deck_[r].value = 0;
    }
    
    for ( i = 0; i < 52; i++)
        deck_[i] = temp[i];
    
}

bool DeckofCards::isEmpty() const{
    return (nextCard_ == 52) ;
}

aCard DeckofCards::deal(){
    if(isEmpty()){//correct this...
        cerr << "deal:  All cards have been dealt..." << endl;
        exit(1);
    }
    
    // return next card and 'remove' it from the deck
    
    return deck_ [ nextCard_++ ];
}

void displayHand(aCard x[], std::string words) {
    
    cout << setw(40) << words <<endl;
    
    toporBottom();
    edges();
    
    displayRowofSuits(x);
    displayRowofValues(x);
    
    edges();
    toporBottom();
}

void displaySuite(char suit, int line) {
    
    switch (suit) {
            
        case 'D':       switch (line) {
            case 0:
            case 4:  cout << "    D    "; break;
            case 1:
            case 3:  cout << "   D D   "; break;
            case 2:  cout << "  D   D  "; break;
        } break;
            
        case 'H':       switch(line) {
            case 0:
            case 2:  cout << "  H   H  "; break;
            case 1:  cout << " H  H  H "; break;
            case 3:  cout << "   H H   "; break;
            case 4:  cout << "    H    "; break;
        } break;
            
        case 'S':       switch(line) {
            case 0:  cout << "    S    "; break;
            case 1:  cout << "   S S   "; break;
            case 2:  cout << " S     S "; break;
            case 3:  cout << "  S S S  "; break;
            case 4:  cout << "    S    "; break;
        } break;
        case 'C':       switch(line) {
            case 0:  cout << "   CCC   "; break;
            case 1:  cout << "    C    "; break;
            case 2:  cout << " C     C "; break;
            case 3:  cout << " CC C CC "; break;
            case 4:  cout << " C     C "; break;
        }
    }
    
}

void displayRowofSuits(aCard x[]){
    
    for (int i = 0; i < 5; i++) { //5 lines
        cout << "   ";
        for (int j = 0; j < 5; j++) {
            cout << "|";
            displaySuite( x[j].suit, i); // suit of card i on line j
            cout << "|  ";
        }
        cout << endl;
    }
}

void toporBottom(){
    cout << "   +++++++++++  +++++++++++  +++++++++++  +++++++++++ "; 
    cout << " +++++++++++ "<<endl;
}

void edges() {
    cout << "   |         |  |         |  |         |  |         |  |       ";  
    cout << "  | "<<endl;
}

void displayRowofValues(aCard x[]) {
    cout << "   ";
    for (int i = 0 ; i < 5; i++ ){
        cout << "|" <<  setw(5) ;
        if (x[i].value >= 2  && x[i].value <= 10){
            cout << x[i].value  ;
        }
        else      switch (x[i].value) {
            case 11:  cout << "    J"; break;
            case 12:  cout << "    Q"; break;
            case 13:  cout << "    K"; break;
            case 14:  cout << "    A"; break;
            default:  cout << " bad";
        }
        cout << setw(3) << " " <<" |  ";
    }
    cout <<endl;
}

void DeckofCards::displayDeck(){
    displayHand(deck_, "Your Cards");
}
the file contains 100 but will not effect the program if you have it or not.
I can't reproduce your problem, but if I had to guess, it's the use of cin.sync() which can cause cin to go into a fail state (and which isn't guaranteed to do anything useful anyway.)
i threw the std::cin.sync() while trying to debug it after the original error occurred. i usually do a std::cin.clear() after every std::cin >> just to clean up anything it might have picked up. i got it kinda working but it still completely ignores this line
getline(std::cin, s); [line 163]
i have no idea what is cin is picking up but this line is never executed/skips over without user input. does anyone know another method of getting a string which includes whitespace?
Last edited on
i usually do a std::cin.clear() after every std::cin >> just to clean up anything it might have picked up.

This doesn't clean anything up. It only resets the state flags.

When you enter the wager the input buffer contains say, "10\n".

The extraction operator extracts the 10 and leaves the '\n'.

After cin.clear() the '\n' is still in the input buffer.

getline(std::cin, s); places "" in s and eats the '\n'.

The solution is to use cin.ignore() or

1
2
getline(std::cin, s); // gets rid of the '\n' in the buffer
getline(std::cin, s); // gets the input 

Last edited on
67
68
69
70
71
72
       std::cin >> wager; //get  
        std::cin.clear(); //clear
    }
    bank-= wager; 
    
    replace(hand, deck); //error occurs here 


When you mix std::cin >> operations with unformatted (such as line oriented) input, the whitespace left in the stream by the formatted input operations is often a problem. I would suggest after line 68 putting in the usual std::cin.ignore() call to remove it from the input stream.

http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3
Topic archived. No new replies allowed.