Infinite Loop problems


As part of an effort to teach myself C++ I've been doing a book-length project which was going pretty well until I had to adapt my program to work with files instead of arrays.

I need these two functions to work together however when use the addBook function to fill up the Inventory.dat file.....

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
void addBook()         
{
	BookData input;
	inventory.open("Inventory.dat", ios::in | ios::out | ios::binary);
	inventory.seekg(0, ios::beg);
	int index = 0;
	long pos;
	pos = inventory.tellp();
	int position = -1;
	bool found = false;
    char info[51];
	char *sptr;
	sptr = info;
	double whole, ret;
	int qty;
	inventory.read(reinterpret_cast<char *>(&input),sizeof(input));
	while (index < NUM_RECORDS && !found)
	{
		

		if (isEmpty(input) == 1)
		{
			found = true;
			
			pos = inventory.tellp();
			pos = pos - sizeof(input);
			
		}
		index++;
		inventory.read(reinterpret_cast<char *>(&input),sizeof(input));
	}
	if (found == false || index == NUM_RECORDS)
	{
		cout << "position " << pos << endl;
		cout << "The inventory is full, you cannot add any more books\n";
		main();
	}
	cout << "pos " << pos << endl;
    cout << "Enter the ISBN: ";
	cin.ignore();
	cin.getline(input.isbn,14);
	strUpper(input.isbn);	 
	cout << "Enter the Title: ";
    cin.getline(input.bookTitle,51);
	strUpper(input.bookTitle);
	cout << "Enter The Author: ";
	cin.getline(input.author,31);
	strUpper(input.author);
	cout << "Enter The Publisher: ";
	cin.getline(input.publisher,31);
    strUpper(input.publisher);
    cout << "Enter The Date: ";
    cin.getline(input.dateAdded,11);
	cout << "Enter The Quantity: ";
	cin >> qty;
	input.qtyOnHand = qty;  
	cout << "Wholesale Cost: $";
	cin >> whole;
	input.wholesale = whole;  
	cout << "Retail Price: $";
	cin >> ret;
	input.retail = ret; 
    cout << endl;
	inventory.seekp(pos, ios::beg);
	inventory.write(reinterpret_cast<char *>(&input),sizeof(input));
	bookInfo(input);
	cout << endl;
    inventory.close();
  
	inventory.open("inventory.dat", ios::in | ios::binary);

	inventory.read(reinterpret_cast<char *>(&input), sizeof(input));

	while(!inventory.eof())
	{
		cout << "Title: ";
		cout << input.bookTitle << endl;
		cout << "Qty: ";
		cout << input.qtyOnHand << endl;
		inventory.read(reinterpret_cast<char *>(&input), sizeof(input));
	}
	
	inventory.close();

	main();
}


No Matter what I do I get serious problems when I use the lookUpBook function...

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
void lookUpBook()
{ 
	BookData input;
	inventory.open("Inventory.dat", ios::in | ios::binary);
	char book[6];
	char *strPtr = NULL;
	char *strPtr2 = NULL;
	char ans;
	int index;
	if(!inventory)
	{
		cout << "error opening file";
                cout << endl;
	}
	cout << "What is the title of the book you wish to lookup?\n";
	cin.ignore();
	cin.getline(book,6);
	strUpper(book);
	for (index = 0; index < NUM_RECORDS; index++)
	{   
		inventory.read(reinterpret_cast<char *>(&input),sizeof(input));
		strPtr = strstr(input.bookTitle,book);
		
	    if (strPtr != NULL)
		{   
			
            cout << " Is " << input.bookTitle << " the book you where searching for? Y/N ";
			cin >> ans;
			if (ans == 'Y' || ans == 'y')
			{
				bookInfo(input);
				cout << endl;
				inventory.seekg(0, ios::beg);
				inventory.close();
				main();

			}
		
		}
	
	}
	if (strPtr == NULL)
	{
		cout << endl;
		cout << "That book is not in the inventory. \n";
		inventory.close();
		cout << endl;
		main();
	
	}
    
}


First it reports an error when it tries to open Inventory.dat however if I search for a book not in the inventory it works ok but if I search for book in the file it sends me into an infinite loop in main! So here is main...

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
int main()
{	

	for (int count = 0; count < NUM_RECORDS; count++)
	{
		inventory.write(reinterpret_cast<char *>(&input),  sizeof(input));
	}
    
	inventory.close();

	int choice = 0;

	while (choice < 1 || choice > 4)
	{
		cout << "Serendipity Booksellers\n";
		cout << "      Main Menu        \n";
		cout << endl;
		cout << "1. Cashier Module\n";
		cout << "2. inventory Database Module\n";
		cout << "3. Report Module\n";
		cout << "4. Exit\n";
		cout << endl;
		cout << "Please enter a number in the range 1-4: ";
		cin >> choice;
		cout << endl;
	}

	switch (choice)
	{
		case 1: cashier();
			break;
		case 2: invMenu();
			break;
        case 3: reports();
			break;
		case 4: cout << "You selected item 4.\n";
			break;
	}
	
	return 0;
}



When I "manually" fill up Inventory.dat the functions works ok and finds the book however using addBook causes it to ignore the cin statements and as I said sends main into an infinite loop. So when I run it and search for a book in the file it goes like this:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4: 2


Serendipity Booksellers
inventory Database

1. Look Up a Book
2. Add a Book
3. Edit a Book's Record
4. Delete a Book
5. Return to Main Menu


Please enter a number in the range 1-5: 1

error opening file

What is the title of the book you wish to lookup?

Gremlins

That book is not in the inventory.



Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:

Serendipity Booksellers
Main Menu

1. Cashier Module
2. inventory Database Module
3. Report Module
4. Exit

Please enter a number in the range 1-4:


You get the point. Any help would be appreciated and as I said I still get the error message but the function terminates properly when the book is not in the file and the functions works when I fill up the file without addBook which in turn seems to work fine.



I didn't read it through carefully, but either this is what is wrong or is something you really want to fix anyway:

You don't want to call Main() from your functions - this is sending you into nested loops: When function X calls Main() it doesn't return to main, it 'opens a new' Main(), so you have: Main (1) calls function X (1) calls Main (2) calls function X (2) calls Main (3)....

Instead you want the functions you call in Main to return. When they do, Main will continue from the line after the function call, and then you can have some sort of loop inside Main to return to the main menu.
I got rid of the calls to main from inside the functions and now the lookUpBook goes into an infinite loop even when searching for a non existent book. I've taken out what I'm certain cannot be the problematic bits of code to make it easier, here is the new main complete with some preliminaries:

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
const int NUM_RECORDS = 20;

fstream inventory("Inventory.dat", ios::in | ios::out | ios::binary);

int choice = 0;
BookData input = {"","","","","",0,0.0,0.0};    // book data structure

int main()
{	

	for (int count = 0; count < NUM_RECORDS; count++)
	{
		inventory.write(reinterpret_cast<char *>(&input), sizeof(input));
	}
    
	inventory.close();


	do{ 
		mainMenu();
		
		

	}while( choice < 10);

	return 0;
}


int addBook()         
{
	BookData input;
	inventory.open("Inventory.dat", ios::in | ios::out | ios::binary);
	inventory.seekg(0, ios::beg);
	int index = 0;
	long pos;
	pos = inventory.tellp();
	int position = -1;
	bool found = false;
	double whole, ret;
	int qty;
	inventory.read(reinterpret_cast<char *>(&input),sizeof(input));
	while (index < NUM_RECORDS && !found)
	{
		

		if (isEmpty(input) == 1)
		{
			found = true;
			
			pos = inventory.tellp();
			pos = pos - sizeof(input);
			
		}
		index++;
		inventory.read(reinterpret_cast<char *>(&input),sizeof(input));
	}
	if (found == false || index == NUM_RECORDS)
	{
		cout << "position " << pos << endl;
		cout << "The inventory is full, you cannot add any more books\n";
		return 0;
	}

    cout << "Enter the ISBN: ";
	cin.ignore();
	cin.getline(input.isbn,14);
	strUpper(input.isbn);	 
............................................................        // skipping  "safe" code

	inventory.seekp(pos, ios::beg);
	inventory.write(reinterpret_cast<char *>(&input),sizeof(input));
	bookInfo(input);
	cout << endl;
    inventory.close();
  
	
return 0;
}



int lookUpBook()
{ 
	BookData input;
	inventory.open("Inventory.dat", ios::in | ios::binary);
	char book[6];
	char *strPtr = NULL;
	char ans;
	int index;
	if(!inventory)
	{
		cout << "error opening file";
	}
	cout << "What is the title of the book you wish to lookup?\n";
	cin.ignore();
	cin.getline(book,6);
	strUpper(book);
	for (index = 0; index < NUM_RECORDS; index++)
	{   
		inventory.read(reinterpret_cast<char *>(&input),sizeof(input));
		strPtr = strstr(input.bookTitle,book);
		
	    if (strPtr != NULL)
		{   
			
            cout << " Is " << input.bookTitle << " the book you where searching for? Y/N ";
			cin >> ans;
			if (ans == 'Y' || ans == 'y')
			{
				bookInfo(input);
				cout << endl;
				inventory.seekg(0, ios::beg);
				inventory.close();

			}
		
		}
	
	}
	if (strPtr == NULL)
	{
		cout << endl;
		cout << "That book is not in the inventory. \n";
		inventory.close();
		cout << endl;
	
	}
 return 0;   
}


And as I said this is marginally worse. This seems to me to be a file opening issue so that's probably whats wrong but I can't see it as I've never used files before. Everything (and this is part of a much larger program) worked perfectly using arrays.
Last edited on
closed account (o3hC5Di1)
Hi there,

Perhaps you've deleted it accidentally pasting your code here, but:

1
2
3
4
5
6
7
//line 19
do{ 
		mainMenu();
		
		

	}while( choice < 10);


I don't see the choice variable being changed there (can't see the mainMenu function either), so from what I can see here, choice will always be as you declared it: int choice = 0; and so it will never be 10, hence an infinite loop.

Hope that helps.

All the best,
NwN
Topic archived. No new replies allowed.