Witts end with this program...

So I have to make a credit card verifier and my god I have never been so frustrated in all my life. The entire source follows, I get 3 runtime errors -

http://i.imgur.com/MXoYNv1.png

that are even less clear than the Visual Studio errors.

What I'm generally trying to do (required in the project) -

Check if the user wants to use assertions (seems to work fine)
Get the card numbers from a file (also works)
Check what brand the card is by taking the first digit and checking if its a 4, 5, 6, or in the case of Amex, 3 and the 2nd digit being 7. (this method works as well)

Also check for the length, greater than or equal to 13, but less than or equal to 16 digits long. (Also seems to work)

Where I get the problems are in the lower methods where all the calculations are done. I realize in SumofDoubleEvenPlace I have no occasions for when length is 15, or 14, or 13, but I'm just trying to get 16 to work for a start...

What this method has to do is, from left to right, double every second number in the card number. With a length of 16, it should skip 16, and start at 15 (which is 14 due to .at using memory locations, 0-15 and not 1-16 like .length)

If the result of any doubling is a two digit number, these two digits are added. So if a card had a 9 in it, that was doubled, you'd get 18. These two added you'd be back to 9. At the end it sums all results together.

For the next method, it does a similar thing except not doubling, simply adding the odd places in the number from right to left (in a 16 length number, position 15, 13, 11, 9, etc)

At the end, this method too sums all the odd places for a particular card together.

Finally, in IsValid, it adds both the final sums together. If this number is divisible by 10 (ends in a zero. For this it has to know ValidNumber's length, and I check that through the thousands place.) the card is VALID, if not, INVALID.

Quite frankly I've rewritten several of these methods over and I'm still throwing the same errors and still having no idea why it's failing so hard.

Some insight would be absolutely fantastic.

Running the example card number 4388576018402626 (which should be invalid)

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
#include <iostream>
#include <fstream>
#include <string>
#include <assert.h>
#include <iomanip>
#define infile "InData.txt"
#define outfile "OutData.txt"
#define errorfile "ErrorData.txt"
#define outfile2 "Sums.txt"

using namespace std;
ifstream ins; //input file
ofstream ons; //valid output file
ofstream ens; //error file
ofstream sums;
ifstream sumsin;

struct CreditCard
{
	string CardNumber;
	string CardBrand;
	int SumProductEven;
	int SumOdd;
	int CardLength;
	string Validity;
};

CreditCard CreditCards[9999];

bool ProcessingOption()
{
	char Affirm;
	bool AssertionUse;

	cout << "Hello, and welcome to Cameron Labut's credit card verifying program." << endl;
	cout << "Would you like to break operations at the first invalid credit card length, or continue with operations and note the invalid card(s)?" << endl;
	cout << "If you want to break on invalid cards, type y, if not, type n" << endl;

	cin >> Affirm;

	if (Affirm == 'y' || Affirm == 'Y')
	{
		AssertionUse = true;

	}
	else if (Affirm = 'n' || Affirm == 'N')
	{
		AssertionUse = false;
	}

		return(AssertionUse);
}

int GetCardNumbers()
{
	int TotalCards;
	TotalCards = 0;

	ins.open(infile);

	if (ins.fail())
	{
		cout << "File open error, verify file exists." << endl;
	}

	do
	{
		ins >> CreditCards[TotalCards].CardNumber;

		TotalCards = TotalCards + 1;

	} while (!ins.eof());

	return(TotalCards);

}

void CreditCardType(int TotalCards)
{
	int TotalCards2; //since the silly arrays wont allow variables, I have to keep setting it to zero as a workaround, instead of the more direct way of actually using the number of cards, I have to loop.
	TotalCards2 = 0;

	do
	{

		if (CreditCards[TotalCards2].CardNumber.at(0) == '4' )
		{
			CreditCards[TotalCards2].CardBrand = "Visa";

		}
		else if (CreditCards[TotalCards2].CardNumber.at(0) == '5')
		{
			CreditCards[TotalCards2].CardBrand = "MasterCard";
		}
		else if (CreditCards[TotalCards2].CardNumber.at(0) == 3 && CreditCards[TotalCards2].CardNumber.at(1) == '7')
		{
			CreditCards[TotalCards2].CardBrand = "American Express";

		}
		else if (CreditCards[TotalCards2].CardNumber.at(0) == '6')
		{
			CreditCards[TotalCards2].CardBrand = "Discover";

		}
		else
		{
			CreditCards[TotalCards2].CardBrand = "Void";
		}

		TotalCards2 = TotalCards2 + 1;


	} while (TotalCards2 < TotalCards);



}

void GetLengthAssertTrue(int TotalCards)
{
	int TotalCards4;
	TotalCards4 = 0;

	do
	{
		if (CreditCards[TotalCards4].CardNumber.length() < 13 || CreditCards[TotalCards4].CardNumber.length() > 16)
		{
			const int i = 0;
			assert(i == 1);
		}
		else if (CreditCards[TotalCards4].CardNumber.length() >= 13 && CreditCards[TotalCards4].CardNumber.length() <= 16)
		{
			CreditCards[TotalCards4].CardLength = CreditCards[TotalCards4].CardNumber.length();

		}

		TotalCards4 = TotalCards4 + 1;

	} while (TotalCards4 < TotalCards);

}


void GetLengthAssertFalse(int TotalCards)
{
	int TotalCards5;
	TotalCards5 = 0;
	int ErrorCount = 1;

	ens.open(errorfile);

	do
	{
		if (CreditCards[TotalCards5].CardNumber.length() < 13 || CreditCards[TotalCards5].CardNumber.length() > 16)
		{
			cout << "WARNING - A card number is invalid, writing relevant data to ErrorData.txt" << endl;

			if (ErrorCount == 1)
			{
				ens << "Invalid Card Numbers due to Length" << endl;
			}

			ens << CreditCards[TotalCards5].CardNumber << endl;

			CreditCards[TotalCards5].CardLength = CreditCards[TotalCards5].CardNumber.length();

			ErrorCount = ErrorCount + 1;

		}
		else if (CreditCards[TotalCards5].CardNumber.length() >= 13 && CreditCards[TotalCards5].CardNumber.length() <= 16)
		{
			CreditCards[TotalCards5].CardLength = CreditCards[TotalCards5].CardNumber.length();
		}

		TotalCards5 = TotalCards5 + 1;

	} while (TotalCards5 < TotalCards);

	ens.close();
}
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
void sumOfDoubleEvenPlace(int TotalCards)
{
	int TotalCards6;
	int PlaceInNumber;
	int Counter;
	TotalCards6 = 0;
	Counter = 0;
	int SumsL16[8];
	int SumsL15;
	int SumsL14;
	int SumsL13;

	do
	{
		if (CreditCards[TotalCards6].CardLength == 16)
		{
			PlaceInNumber = 14;

			while (Counter < 8 && PlaceInNumber >=0)
			{

				SumsL16[Counter] = CreditCards[TotalCards6].CardNumber.at(PlaceInNumber);

				SumsL16[Counter] = SumsL16[Counter] * 2;

				if (SumsL16[Counter] == 18)
				{
					SumsL16[Counter] = 9;
				}
				else if (SumsL16[Counter] == 16)
				{
					SumsL16[Counter] = 7;
				}
				else if (SumsL16[Counter] == 14)
				{
					SumsL16[Counter] = 5;
				}
				else if (SumsL16[Counter] == 12)
				{
					SumsL16[Counter] = 3;
				}
				else if (SumsL16[Counter] == 10)
				{
					SumsL16[Counter] = 1;
				}
				else
				{
					SumsL16[Counter] = SumsL16[Counter];
				}


				PlaceInNumber = PlaceInNumber - 2;
				Counter = Counter + 1;

				if (Counter == 8)
				{
					CreditCards[TotalCards6].SumProductEven = SumsL16[0] + SumsL16[1] + SumsL16[2] + SumsL16[3] + SumsL16[4] + SumsL16[5] + SumsL16[6] + SumsL16[7];

				}

			}



		}

		TotalCards6 = TotalCards6 + 1;

	} while (TotalCards6 < TotalCards);

}


void sumOfOddPlace(int TotalCards)
{
	int SubTotal;
	int TotalCards7;
	int PlaceInNumber;
	int PlaceInNumber2;
	TotalCards7 = 0;

	do
	{
		if (CreditCards[TotalCards7].CardLength == 16)
		{
			PlaceInNumber = 15;
			PlaceInNumber2 = 13;

			SubTotal = CreditCards[TotalCards7].CardNumber.at(PlaceInNumber) + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);

			do
			{

				PlaceInNumber2 = PlaceInNumber2 - 2;
				SubTotal = SubTotal + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);
				if (PlaceInNumber2 == 1)
				{
					CreditCards[TotalCards7].SumOdd = SubTotal;
				}
			} while (PlaceInNumber2 > 0);
		}
		else if (CreditCards[TotalCards7].CardLength == 15)
		{
			PlaceInNumber = 14;
			PlaceInNumber2 = 12;

			SubTotal = CreditCards[TotalCards7].CardNumber.at(PlaceInNumber) + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);

			do
			{

				PlaceInNumber2 = PlaceInNumber2 - 2;
				SubTotal = SubTotal + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);
				if (PlaceInNumber2 == 0)
				{
					CreditCards[TotalCards7].SumOdd = SubTotal;
				}

			} while (PlaceInNumber2 >= 0);
		}
		else if (CreditCards[TotalCards7].CardLength == 14)
		{
			PlaceInNumber = 13;
			PlaceInNumber2 = 11;

			SubTotal = CreditCards[TotalCards7].CardNumber.at(PlaceInNumber) + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);

			do
			{
				PlaceInNumber2 = PlaceInNumber2 - 2;
				SubTotal = SubTotal + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);
				if (PlaceInNumber2 == 1)
				{
					CreditCards[TotalCards7].SumOdd = SubTotal;
				}

			} while (PlaceInNumber2 > 0);

		}
		else if (CreditCards[TotalCards7].CardLength == 13)
		{
			PlaceInNumber = 12;
			PlaceInNumber2 = 10;

			SubTotal = CreditCards[TotalCards7].CardNumber.at(PlaceInNumber) + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);

			do
			{
				PlaceInNumber2 = PlaceInNumber2 - 2;
				SubTotal = SubTotal + CreditCards[TotalCards7].CardNumber.at(PlaceInNumber2);
				if (PlaceInNumber2 == 0)
				{
					CreditCards[TotalCards7].SumOdd = SubTotal;
				}

			} while (PlaceInNumber2 >= 0);
		}
		TotalCards7 = TotalCards7 + 1;

	} while (TotalCards7 < TotalCards);

}



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
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
void isValid(int TotalCards, bool AssertionUse)
{
	int TotalCards3;
	TotalCards3 = 0;
	int FinalSum;
	int Fail = 0;
	string ValidNumber;
	int ErrorCount;


	if (AssertionUse == true)
	{
		GetLengthAssertTrue(TotalCards);
		sumOfDoubleEvenPlace(TotalCards);
		sumOfOddPlace(TotalCards);


		do
		{
			FinalSum = CreditCards[TotalCards3].SumProductEven + CreditCards[TotalCards3].SumOdd;



			sums.open(outfile2);

			sums << FinalSum << endl;

			sums.close();

			sumsin.open(outfile2);

			sumsin >> ValidNumber;

			sumsin.close();

			remove("Sums.txt");


			if (ValidNumber.length() == 4) //checks if sum in the thousands place, hopefully there are no sums longer than this.
			{
				if (ValidNumber.at(3) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(3) > 0 || ValidNumber.at(3) < 0)
				{
					assert(Fail == 1);
				}
			}
			else if (ValidNumber.length() == 3)
			{
				if (ValidNumber.at(2) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(2) > 0 || ValidNumber.at(2) < 0)
				{
					assert(Fail == 1);
				}
			}
			else if (ValidNumber.length() == 2)
			{
				if (ValidNumber.at(1) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(1) > 0 || ValidNumber.at(1) < 0)
				{
					assert(Fail == 1);
				}
			}
			else if (ValidNumber.length() == 1)
			{
				if (ValidNumber.at(0) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(0) > 0 || ValidNumber.at(0) < 0)
				{
					assert(Fail == 1);
				}
			}
			else if (ValidNumber.length() > 4 || ValidNumber.length() < 0)
			{
				cout << "Invalid sum" << endl;
			}

			TotalCards3 = TotalCards3 + 1;

		} while (TotalCards3 < TotalCards);

	}
	else if (AssertionUse == false)
	{
		GetLengthAssertFalse(TotalCards);
		sumOfDoubleEvenPlace(TotalCards);
		sumOfOddPlace(TotalCards);
		ErrorCount = 1;


		do
		{
			FinalSum = CreditCards[TotalCards3].SumProductEven + CreditCards[TotalCards3].SumOdd;

			sums.open(outfile2);

			sums << FinalSum << endl;

			sums.close();

			sumsin.open(outfile2);

			sumsin >> ValidNumber;

			sumsin.close();

			remove("Sums.txt");

			if (ValidNumber.length() == 4) //checks if sum in the thousands place, hopefully there are no sums longer than this.
			{
				if (ValidNumber.at(3) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(3) > 0 || ValidNumber.at(3) < 0)
				{

					cout << "Invalid number found, writing relevant data to error file." << endl;

					ens.open(errorfile);

					if (ErrorCount == 1)
					{
						ens << "Ivalid Card Numbers due to Indivisibility by 10" << endl;
						ErrorCount = ErrorCount + 1;
					}

					ens << CreditCards[TotalCards3].CardNumber << endl;

					ens.close();

				}
			}
			else if (ValidNumber.length() == 3)
			{
				if (ValidNumber.at(2) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(2) > 0 || ValidNumber.at(2) < 0)
				{
					cout << "Invalid number found, writing relevant data to error file." << endl;

					ens.open(errorfile);
					if (ErrorCount == 1)
					{
						ens << "Ivalid Card Numbers due to Indivisibility by 10" << endl;
						ErrorCount = ErrorCount + 1;
					}

					CreditCards[TotalCards3].Validity = "INVALID";
					ens << CreditCards[TotalCards3].CardNumber << endl;

					ens.close();
				}
			}
			else if (ValidNumber.length() == 2)
			{
				if (ValidNumber.at(1) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(1) > 0 || ValidNumber.at(1) < 0)
				{
					cout << "Invalid number found, writing relevant data to error file." << endl;

					ens.open(errorfile);
					if (ErrorCount == 1)
					{
						ens << "Ivalid Card Numbers due to Indivisibility by 10" << endl;
						ErrorCount = ErrorCount + 1;
					}

					CreditCards[TotalCards3].Validity = "INVALID";
					ens << CreditCards[TotalCards3].CardNumber << endl;

					ens.close();
				}
			}
			else if (ValidNumber.length() == 1)
			{
				if (ValidNumber.at(0) == 0)
				{
					CreditCards[TotalCards3].Validity = "VALID";
				}
				else if (ValidNumber.at(0) > 0 || ValidNumber.at(0) < 0)
				{
					cout << "Invalid number found, writing relevant data to error file." << endl;

					ens.open(errorfile);
					if (ErrorCount == 1)
					{
						ens << "Ivalid Card Numbers due to Indivisibility by 10" << endl;
						ErrorCount = ErrorCount + 1;
					}

					CreditCards[TotalCards3].Validity = "INVALID";
					ens << CreditCards[TotalCards3].CardNumber << endl;

					ens.close();
				}
			}
			else if (ValidNumber.length() > 4 || ValidNumber.length() < 0)
			{
				cout << "Invalid sum" << endl;
			}

			TotalCards3 = TotalCards3 + 1;

		} while (TotalCards3 < TotalCards);

	}


}



void Display(int TotalCards)
{
	int TotalCards8;
	TotalCards8 = 0;

	ons.open(outfile);

	cout << "Preparing to display data... data also displayed in the file OutData.txt" << endl;
	cout << setw(16) << "Card#" << setw(16) << "Type" << setw(8) << "Length" << setw(10) << "Validity" << endl;
	ons << setw(16) << "Card#" << setw(16) << "Type" << setw(8) << "Length" << setw(10) << "Validity" << endl;

	do
	{
		cout << setw(16) << CreditCards[TotalCards8].CardNumber << setw(16) << CreditCards[TotalCards8].CardBrand << setw(4) << CreditCards[TotalCards8].CardLength << setw(7) << CreditCards[TotalCards8].Validity << endl;
		ons << setw(16) << CreditCards[TotalCards8].CardNumber << setw(16) << CreditCards[TotalCards8].CardBrand << setw(4) << CreditCards[TotalCards8].CardLength << setw(7) << CreditCards[TotalCards8].Validity << endl;

		TotalCards8 = TotalCards8 + 1;

	} while (TotalCards8 < TotalCards);

	ons.close();

}

int main()
{
	int NoCards;
	bool Assert;

	Assert = ProcessingOption();
	NoCards = GetCardNumbers();
	CreditCardType(NoCards);	
	isValid(NoCards, Assert);
	Display(NoCards);

	ins.close();
	ens.close();
	ons.close();

	system("PAUSE");
	return(0);

}
Last edited on
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
#include <iostream>
#include <cctype>
#include <cassert>
#include <vector>
#include <algorithm>
#include <string>

int double_it( int digit )
{
    assert( digit >= 0 && digit <= 9 ) ; // 'if the user wants to use assertions'

    const int dbl[] = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 } ;
    return dbl[digit] ;
}

 // from right to left, double every second number in the card
 // http://www.mochima.com/tutorials/vectors.html
 int sum_of_double_even_place_right_to_left( std::vector<int> digits ) // passed by value
 {
     // http://en.cppreference.com/w/cpp/algorithm/reverse
     std::reverse( digits.begin(), digits.end() ) ; // reverse the digits
     int sum = 0 ;

     // for every second digit, starting at position 1
     for( std::size_t i = 1 ; i < digits.size() ; i += 2 ) sum += double_it( digits[i] ) ;
     return sum ;
 }

 int sum_of_odd_places_right_to_left( std::vector<int> digits ) // passed by value
 {
     std::reverse( digits.begin(), digits.end() ) ; // reverse the digits
     int sum = 0 ;

     // for every second digit, starting at position 0
     for( std::size_t i = 1 ; i < digits.size() ; i += 2 ) sum += digits[i] ;
     return sum ;
 }

 bool final_sum_ends_in_zero( std::vector<int> digits )
 {
     const int final_sum = sum_of_double_even_place_right_to_left(digits) +
                           sum_of_odd_places_right_to_left(digits) ;
     return final_sum%10 == 0 ;
 }

 std::vector<int> string_to_vector( std::string digits )
 {
     std::vector<int> result ;

     for( char c : digits ) // http://www.stroustrup.com/C++11FAQ.html#for
     {
         // http://en.cppreference.com/w/cpp/string/byte/isdigit
         assert( std::isdigit(c) ) ; // 'if the user wants to use assertions'

         // http://en.cppreference.com/w/cpp/container/vector/push_back
         result.push_back( c - '0' ) ; // ( '6' - '0' ) == 6 etc.
     }

     return result ;
 }

int main()
{
    const std::string card = "4388576018402626" ;
    std::cout << std::boolalpha << "final_sum_ends_in_zero? "
              << final_sum_ends_in_zero( string_to_vector(card) ) << '\n' ;
}

http://coliru.stacked-crooked.com/a/38328294bdcab203
I have seen that

std::vector

notation before and wondered why it looks so different to the C++ I'm learning, although I appreciate your help, we can't use anything we didnt learn yet (Only up to Classes), so no vectors nor that strange syntax yet, not like I would plagiarise someone else's work, I just need to figure out what's wrong with mine, other than apparently being way, way too long according to that tiny one you posted.
The logic is straightforward - and it will work with any sequence (vector, string, c-style array) of digits. To access alternate elements in a sequence from right to left, a simple approach is to reverse the sequence and access elements at positions 1,3,5 ... or at positions 0,2,4 ... till end of (reversed) sequence.

For instance, the same program without <vector>, without <algorithm>, without <cctype>

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 <cassert>
#include <string>

bool is_digit( char c ) { return c >= '0' && c <= '9' ; }

int double_it( char digit )
{
    assert( is_digit(digit) ) ;

    const int dbl[] = { 0, 2, 4, 6, 8, 1, 3, 5, 7, 9 } ;
    const int ival = digit - '0' ; // integer value of digit
    return dbl[ival] ;
}

std::string reverse( std::string str )
{
     std::string rev ;
     for( std::size_t i = 0 ; i < str.size() ; ++i ) rev = str[i] + rev ;
     return rev ;
}

 // from right to left, double every second number in the card
 int sum_of_double_even_place_right_to_left( std::string digits )
 {
     const std::string rev = reverse(digits) ;
     int sum = 0 ;
     // for every second digit, starting at position 1
     for( std::size_t i = 1 ; i < rev.size() ; i += 2 ) sum += double_it( rev[i] ) ;
     return sum ;
 }

 int sum_of_odd_places_right_to_left( std::string digits )
 {
     const std::string rev = reverse(digits) ;
     int sum = 0 ;
     // for every second digit, starting at position 0
     for( std::size_t i = 1 ; i < rev.size() ; i += 2 )
     {
         const int ival = digits[i] - '0' ; // integer value of digit
         sum += ival ;
     }
     return sum ;
 }

 bool final_sum_ends_in_zero( std::string digits )
 {
     for( std::size_t i = 0 ; i < digits.size() ; ++i ) assert( is_digit( digits[i] ) ) ;

     const int final_sum = sum_of_double_even_place_right_to_left(digits) +
                           sum_of_odd_places_right_to_left(digits) ;
     return final_sum%10 == 0 ;
 }

int main()
{
    const std::string card = "4388576018402626" ;
    std::cout << std::boolalpha << "final_sum_ends_in_zero? "
              << final_sum_ends_in_zero(card) << '\n' ;
}
Culbrelai said
I just need to figure out what's wrong with mine,


When I include one credit card in my InData.txt and use the debugger, GetCardNumbers() function returns with a value of 2. I believe this is the source of your error messages.

I also noticed that ProcessingOption() has one assignment (=) in an if where you intend for a comparison (==).
Alright so I've rewritten the entire thing, making sure to check if it works method by method.

Still doesn't work and am about to cry lol...

I would rather not use that probably excellent solution above Pheininger's post as it shows I went to outside sources for help plus I don't want to use stuff we haven't learned yet.

I denoted with a comment up to where it worked as intended. IsValid once again is being a betch.

Rather than use global variables (professor hates them) I set CreditCards[0].TotalCards to however many credit cards the file stream picked up. (Which worked correctly. Output 3 when I checked it, which is correct because in the file there were indeed 3 numbers,

4388576018402626
4381454101745226
4235454257345279

Whichever (assert is true or false) in IsValid both seem to fail.

I realize CreditCards[0].TotalCards and the return value for the second method down are the same number.

These errors seem to pretty much repeat every time I click continue in sort of a cyclical fashion, albeit with different memory locations.

http://i.imgur.com/6hYqJTl.png

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
#include <fstream>
#include <assert.h>
#include <string>
#include <iostream>
#define infile "Numbers.txt"
#define errorfile "InvalidCards.txt"

using namespace std;
ifstream ins;
ofstream ens;

struct CreditCard
{
	string Validity;
	string CardNumber;
	string CardType;
	int TotalCards; // only stored in the first (0) member of the array, denotes total cards.
	int CardLength;
};

CreditCard CreditCards[9998];

bool AssertCheck()
{
	char Affirm;
	bool Assert;
	cout << "Hello, and welcome to xxx's credit card validating program. Would you like to break all operations when an invalid number is found, or write the offending card(s) to an error file and continue?" << endl;
	cout << "If you would like to break on finding an invalid card, enter y, if you want to continue when finding an invalid card, type n." << endl;

	cin >> Affirm;

	if (Affirm == 'y' || Affirm == 'Y')
	{
		Assert = true;
	}
	else if (Affirm == 'n' || Affirm == 'N')
	{
		Assert = false;
	}
	else
	{
		cout << "Sorry, you have entered an invalid answer. Please restart the program and try again" << endl;
		system("PAUSE");
	}

	return(Assert);

}

int InputCards() //returns number of cards
{
	ins.open(infile);
	int CreditCardCounter;
	CreditCardCounter = 0;

	if (ins.fail())
	{
		cout << "The file containing the card numbers could not be opened, please be sure that Numbers.txt exists in the main directory." << endl;
	}

	do
	{
		getline(ins,CreditCards[CreditCardCounter].CardNumber,'\n');

		CreditCardCounter = CreditCardCounter + 1;

		if (ins.eof())
		{
			CreditCards[0].TotalCards = CreditCardCounter;
			return(CreditCardCounter);

		}

	} while (!ins.eof());

	ins.close();

	//works up to here, 2:02 PM 11/29/14
}

string CreditCardType(int Assert)
{
	string Type;

	if (Assert == true)
	{
		if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 4)
		{
			Type = "Visa";
			return(Type);
		}
		else if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 5)
		{
			Type = "MasterCard";
			return(Type);
		}
		else if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 3 && CreditCards[CreditCards[0].TotalCards].CardNumber.at(1) == 7)
		{
			Type = "AmericanExpress";
			return(Type);
		}
		else if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 6)
		{
			Type = "Discover";
			return(Type);
		}
		else
		{
			int False;
			False = 1;
			assert(False == 2);
		}
	}
	else if (Assert == false)
	{
		if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 4)
		{
			Type = "Visa";
			return(Type);
		}
		else if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 5)
		{
			Type = "MasterCard";
			return(Type);
		}
		else if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 3 && CreditCards[CreditCards[0].TotalCards].CardNumber.at(1) == 7)
		{
			Type = "AmericanExpress";
			return(Type);
		}
		else if (CreditCards[CreditCards[0].TotalCards].CardNumber.at(0) == 6)
		{
			Type = "Discover";
			return(Type);
		}
		else
		{
			ens.open(errorfile);

			int ErrorCount;
			ErrorCount = 1;
			
			if (ErrorCount == 1)
			{
				ens << "Invalid Card Numbers due to no known type." << endl;
				ens << CreditCards[CreditCards[0].TotalCards].CardNumber << endl;

				ErrorCount = ErrorCount + 1;
			}
			else if (!ErrorCount == 1)
			{
				ens << CreditCards[CreditCards[0].TotalCards].CardNumber << endl;
			}

		}
	}
}

void IsValid(int Assert)
{
	do
	{
		CreditCards[CreditCards[0].TotalCards].CardType = CreditCardType(Assert);

		CreditCards[0].TotalCards = CreditCards[0].TotalCards - 1;

	} while (CreditCards[0].TotalCards > 0);


}

int main()
{
	bool AssertionCheck;
	int NumberOfCards;
	int CurrentCard;

	CurrentCard = 0;

	AssertionCheck = AssertCheck();
	NumberOfCards = InputCards();
	IsValid(AssertionCheck);


	system("PAUSE");

}
Last edited on
Topic archived. No new replies allowed.