Last element of vector always disappears (C++)

  • (2 Pages)
  • +
  • 1
  • 2

15 Replies - 590 Views - Last Post: 08 February 2012 - 06:48 AM Rate Topic: -----

Topic Sponsor:

#1 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Last element of vector always disappears (C++)

Posted 07 February 2012 - 10:50 AM

I've been having this problem recently:

I wrote this code which, practically, reads lines of text from a text file (e.g. Microsoft Notepad file) and stores them into a vector. Each line has three parts: the product code, the product amount and the product name. The user is offered, via option number 1, to buy a product with the corresponding code and a certain amount of it. When a user buys a product (and a certain amount of it below the offered one), the amount of a product remaining is stored in place of the previous amount of product.
But whenever I the program shows all the other products (besides the one that has been updated because of buying), the last product is missing (practically, a last vector element).
What could be causing this problem? I've tried all stuff, but can't remember anything anymore. After this, I have to write all the current vector elements over (overwrite) the lines in a text file that were previously taken into the program.
But that doesn't seem to be the problem, I can do that on my own, the only problem being the last vector element missing part.
Here's my code:

Main.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iosfwd>
#include <algorithm>
#include <sstream>
using namespace std;

// Variables
	int code;
		string userCode;				// user specified product code
	int amount;
		int userAmount;				// user specified product amount
		string stringAmount;			// product amount as string
		int remainingAmount;
	string name;
	string line;
	vector<string> allLines;		// vector to contain text lines
		string currentLine;			// current line in element search
		int r;								// used for going through each vector element

// Buy a product
void buyProduct()
{
	cout << "\nPlease enter code of product you want to buy:\n";
	cin >> userCode;

	cout << "\nPlease enter amount of product you want to buy:\n";
	cin >> userAmount;

	cout << endl;

	// Going through the vector elements and looking for product code
	for (r = 0; r < allLines.size(); r++)
	{
		currentLine = allLines[r];

		// Find the entered code within a line
		if (string::npos != currentLine.find(userCode + " "))
		{
			cout << "\nFound at line number " << (r+1) << endl;

			// Extract the second word (product amount) from a line
			size_t pos1 = allLines[r].find(' ') + 1;
			size_t pos2 = allLines[r].find(' ', pos1);

			string secondString = allLines[r].substr(pos1, (pos2 - pos1));

			// Convert String to int
			amount = atoi(secondString.c_str());

			// Error message for wrongly entered product code
			if (!(string::npos != currentLine.find(userCode + " ")) && r == (allLines.size()-1))
			{
				cout << "\nProduct not found! Please try again." << endl;
				buyProduct();
			}

			// Subtract the entered amount from the available amount
			if (userAmount <= amount && userAmount >= 0)
			{
				remainingAmount = amount - userAmount;
				
				stringstream ss;					// create stream for converting int to String
				ss << remainingAmount;		
				stringAmount = ss.str();	   // put the contents of the stream (int) into String
			} 

			if (!(userAmount <= amount && userAmount >= 0))
			{
				cout << "\nProduct amount invalid! Please try again." << endl;
				buyProduct();
			}

			// Extract the third word (product name) from a line
			string thirdWord = allLines[r].substr(pos2 + 1);

			// Store the updated product back into the corresponding vector position
			allLines[r] = userCode + " " + stringAmount + " " + thirdWord;

			break;

		}

	}

	for (int t = 0; t < allLines.size() - 1; ++t)
	{
		cout << endl;
		cout << allLines[t];
	}

	getch();
}


// Main method / program
void main()
{

	ifstream myfile ("items.txt");

	cout << "Displaying items.txt contents:\n\n";

	// Opening a file and sending to output
	if (myfile.is_open())
	{
		cout << endl;
		
		// Empty a vector of lines if not empty
		if (allLines.size() > 0)
		{
			allLines.erase(allLines.begin(), allLines.end());
		}

		// Send file lines to output
		while (myfile.good())
		{
			getline (myfile,line);
			cout << line << endl;

			// Insert a line into a vector
			allLines.push_back(line);
		}

		// Closing a file
		myfile.close();
		cout << endl;						 
	}


	else cout << "\nUnable to open file\n";

	cout << "\nNumber of lines: " << (int) allLines.size() << endl;


	int option;

	cout << "\n\nChoose an option (enter 1 - 3): \n"
		<< "1. Buy product\n"
		<< "2. Display products\n"
		<< "3. Exit\n\n";

	cin >> option;

	switch (option)
	{
	case 1: buyProduct();
	case 2: system("CLS"); main();
	case 3: exit(1);
	default:
		{
			cout << "\n\nInvalid option! Try again.\n";
			main();
		}
	}
}


And here is the text file to use for demonstration (put it in the same place as a Main.cpp file):

items.txt
50320 40 Monitor
20334 80 Mouse
11299 10 Speakers
29931 50 USB
50223 10 Camera

This post has been edited by boris90: 07 February 2012 - 10:53 AM


Is This A Good Question/Topic? 0
  • +

Replies To: Last element of vector always disappears (C++)

#2 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 10:54 AM

There are several problems with your code. First main must be defined to return an int and you should return an int from this function. Second you can not recursively call main() in a C++ program. Third you should not call exit() in a C++ program, this C function does not call C++ destructors properly. Next you should not use eof(), good() ect to control your entry loop. Doing this will usually end up creating errors by having too few or too many lines inputted. It is usually best to use the read operation to control the loop.

// Send file lines to output
//		while (myfile.good())  // This can cause problems.
//		{
//			getline (myfile,line);
    // This will read the line and only process the rest of the
    // loop if the read succeeds.
    while(getline(myfile,line)) 
    {



And finally you should stop using all the global variables. Using global variables will make your program harder to read and debug. Learn to pass the required values to and from your functions. You may want to study the links in my signature if you are not sure how to do this.


Jim

This post has been edited by jimblumberg: 07 February 2012 - 11:05 AM

Was This Post Helpful? 0
  • +
  • -

#3 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 01:31 PM

View Postjimblumberg, on 07 February 2012 - 06:54 PM, said:

There are several problems with your code. First main must be defined to return an int and you should return an int from this function. Second you can not recursively call main() in a C++ program. Third you should not call exit() in a C++ program, this C function does not call C++ destructors properly. Next you should not use eof(), good() ect to control your entry loop. Doing this will usually end up creating errors by having too few or too many lines inputted. It is usually best to use the read operation to control the loop.

// Send file lines to output
//		while (myfile.good())  // This can cause problems.
//		{
//			getline (myfile,line);
    // This will read the line and only process the rest of the
    // loop if the read succeeds.
    while(getline(myfile,line)) 
    {



And finally you should stop using all the global variables. Using global variables will make your program harder to read and debug. Learn to pass the required values to and from your functions. You may want to study the links in my signature if you are not sure how to do this.


Jim


Thanks, Jim, for all these guidelines. I'll try to follow them in future, but I still need to solve this problem with the last element of a vector disappearing. I tried your method, and, just as I thought, nothing specially happened. Does anyone else know how to solve this? Thanks in advance.
Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 01:39 PM

What do you mean by the last vector is disappearing?

Jim
Was This Post Helpful? 0
  • +
  • -

#5 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 03:17 PM

View Postjimblumberg, on 07 February 2012 - 09:39 PM, said:

What do you mean by the last vector is disappearing?

Jim


Well, it'd probably be the best if you could compile the code and see for yourself, and I'd give you the instructions. If you go for that, when the program starts, just enter 1 as an option, then enter one of the codes of the products (5 digit numbers), then an amount (less than the number which corresponds to the entered code) and you'll see. But if no, well, it's about the last element of the vector not showing. It appears as if it's lost. I output the contents of a vector after it being edited and it doesn't display the last element of the vector at all. Say I, for example, had a vector of integers containing numbers 1, 2, 3, 4 and 5. Then, if I edit the vector by putting number, say, 6, instead of any one of the elements of the vector (except for the last one), the number 5 disappears. Whether it be 6, 2, 3, 4 or 1, 6, 3, 4 or 1, 2, 6, 4, the last element 5 will never show. If you can, try it for yourself to better understand what I'm talking about.

Thanks again.
Was This Post Helpful? 0
  • +
  • -

#6 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 03:31 PM

Quote

Well, it'd probably be the best if you could compile the code and see for yourself, and I'd give you the instructions


Your code will not compile on my machine. You need to fix the errors that I pointed out in my previous post, so I can compile your code.

Jim
Was This Post Helpful? 0
  • +
  • -

#7 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 03:41 PM

View Postjimblumberg, on 07 February 2012 - 11:31 PM, said:

Quote

Well, it'd probably be the best if you could compile the code and see for yourself, and I'd give you the instructions


Your code will not compile on my machine. You need to fix the errors that I pointed out in my previous post, so I can compile your code.

Jim


As I've already told you: I already tried your method and it worked the same way as it did before - it makes no difference. And what kind of code wouldn't compile on your compiler! :D
You should be able to compile anything, you're one of the main guys here on these forums!

Anyway, you could do it for yourself. It's just one line of code, for Christ's sake. Write the version you told me would work and try it. It's not that I don't feel like doing it, but you could do it while it's in your text editor for compiling ("on the go").
Was This Post Helpful? 0
  • +
  • -

#8 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 03:48 PM

The following snippet has several errors, causing your program not to compile.
void main()
{

	ifstream myfile ("items.txt");

	cout << "Displaying items.txt contents:\n\n";

	// Opening a file and sending to output
	if (myfile.is_open())
	{
		cout << endl;
		
		// Empty a vector of lines if not empty
		if (allLines.size() > 0)
		{
			allLines.erase(allLines.begin(), allLines.end());
		}

		// Send file lines to output
		while (myfile.good())
		{
			getline (myfile,line);
			cout << line << endl;

			// Insert a line into a vector
			allLines.push_back(line);
		}

		// Closing a file
		myfile.close();
		cout << endl;						 
	}


	else cout << "\nUnable to open file\n";

	cout << "\nNumber of lines: " << (int) allLines.size() << endl;


	int option;

	cout << "\n\nChoose an option (enter 1 - 3): \n"
		<< "1. Buy product\n"
		<< "2. Display products\n"
		<< "3. Exit\n\n";

	cin >> option;

	switch (option)
	{
	case 1: buyProduct();
	case 2: system("CLS"); main(); ////////// ERROR
	case 3: exit(1);
	default:
		{
			cout << "\n\nInvalid option! Try again.\n";
			main();  //////////// ERROR
		}
	}
}


The first error is void main(). The function main must be defined as returning an int, int main().

Another error is you can not call main in any function, including main. You need to rework your program to use the proper looping constructs.

As I said your program will not compile, you need to fix your mistakes. This is your assignment not mine.


Jim
Was This Post Helpful? 0
  • +
  • -

#9 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 03:55 PM

View Postjimblumberg, on 07 February 2012 - 11:48 PM, said:

The following snippet has several errors, causing your program not to compile.
void main()
{

	ifstream myfile ("items.txt");

	cout << "Displaying items.txt contents:\n\n";

	// Opening a file and sending to output
	if (myfile.is_open())
	{
		cout << endl;
		
		// Empty a vector of lines if not empty
		if (allLines.size() > 0)
		{
			allLines.erase(allLines.begin(), allLines.end());
		}

		// Send file lines to output
		while (myfile.good())
		{
			getline (myfile,line);
			cout << line << endl;

			// Insert a line into a vector
			allLines.push_back(line);
		}

		// Closing a file
		myfile.close();
		cout << endl;						 
	}


	else cout << "\nUnable to open file\n";

	cout << "\nNumber of lines: " << (int) allLines.size() << endl;


	int option;

	cout << "\n\nChoose an option (enter 1 - 3): \n"
		<< "1. Buy product\n"
		<< "2. Display products\n"
		<< "3. Exit\n\n";

	cin >> option;

	switch (option)
	{
	case 1: buyProduct();
	case 2: system("CLS"); main(); ////////// ERROR
	case 3: exit(1);
	default:
		{
			cout << "\n\nInvalid option! Try again.\n";
			main();  //////////// ERROR
		}
	}
}


The first error is void main(). The function main must be defined as returning an int, int main().

Another error is you can not call main in any function, including main. You need to rework your program to use the proper looping constructs.

As I said your program will not compile, you need to fix your mistakes. This is your assignment not mine.


Jim


Fine, fine. I'll do it and I'll give you the 'reworked' code.
Was This Post Helpful? 0
  • +
  • -

#10 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 04:14 PM

OK, here's what I've done. I can't seem to remember any better way to recursively call the main function (call it again), since I really need that (to call it again), and writing any additional code would really make my whole code filled with, well - not c*ap, but more unreadable code for sure. So, I changed the main function as you requested, the while loop with the getline() function... I left the calls to main() method, because I don't know any other way to do this. And that's why I'm here, to tell me how I could do this, right?

So... here it is:


#include <iostream>
#include <fstream>
#include <string>
#include <conio.h>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <iosfwd>
#include <algorithm>
#include <sstream>
using namespace std;

// Variables
	int code;
		string userCode;				// user specified product code
	int amount;
		int userAmount;				// user specified product amount
		string stringAmount;			// product amount as string
		int remainingAmount;
	string name;
	string line;
	vector<string> allLines;		// vector to contain text lines
		string currentLine;			// current line in element search
		int r;								// used for going through each vector element

// Buy a product
void buyProduct()
{
	cout << "\nPlease enter code of product you want to buy:\n";
	cin >> userCode;

	cout << "\nPlease enter amount of product you want to buy:\n";
	cin >> userAmount;

	cout << endl;

	// Going through the vector elements and looking for product code
	for (r = 0; r < allLines.size(); r++)
	{
		currentLine = allLines[r];

		// Find the entered code within a line
		if (string::npos != currentLine.find(userCode + " "))
		{
			cout << "\nFound at line number " << (r+1) << endl;

			// Extract the second word (product amount) from a line
			size_t pos1 = allLines[r].find(' ') + 1;
			size_t pos2 = allLines[r].find(' ', pos1);

			string secondString = allLines[r].substr(pos1, (pos2 - pos1));

			// Convert String to int
			amount = atoi(secondString.c_str());

			// Error message for wrongly entered product code
			if (!(string::npos != currentLine.find(userCode + " ")) && r == (allLines.size()-1))
			{
				cout << "\nProduct not found! Please try again." << endl;
				buyProduct();
			}

			// Subtract the entered amount from the available amount
			if (userAmount <= amount && userAmount >= 0)
			{
				remainingAmount = amount - userAmount;
				
				stringstream ss;					// create stream for converting int to String
				ss << remainingAmount;		
				stringAmount = ss.str();	   // put the contents of the stream (int) into String
			} 

			if (!(userAmount <= amount && userAmount >= 0))
			{
				cout << "\nProduct amount invalid! Please try again." << endl;
				buyProduct();
			}

			// Extract the third word (product name) from a line
			string thirdWord = allLines[r].substr(pos2 + 1);

			// Store the updated product back into the corresponding vector position
			allLines[r] = userCode + " " + stringAmount + " " + thirdWord;

			break;

		}

	}

	for (int t = 0; t < allLines.size() - 1; ++t)
	{
		cout << endl;
		cout << allLines[t];
	}

	getch();
}


// Main method / program
int main()
{

	ifstream myfile ("items.txt");

	cout << "Displaying items.txt contents:\n\n";

	// Opening a file and sending to output
	if (myfile.is_open())
	{
		cout << endl;
		
		// Empty a vector of lines if not empty
		if (allLines.size() > 0)
		{
			allLines.erase(allLines.begin(), allLines.end());
		}

		// Send file lines to output
		while (getline (myfile,line))
		{
			
			cout << line << endl;

			// Insert a line into a vector
			allLines.push_back(line);
		}

		// Closing a file
		myfile.close();
		cout << endl;						 
	}


	else cout << "\nUnable to open file\n";

	cout << "\nNumber of lines: " << (int) allLines.size() << endl;


	int option;

	cout << "\n\nChoose an option (enter 1 - 3): \n"
		<< "1. Buy product\n"
		<< "2. Display products\n"
		<< "3. Exit\n\n";

	cin >> option;

	switch (option)
	{
	case 1: buyProduct();
	case 2: system("CLS"); main();
	case 3: exit(1);
	default:
		{
			cout << "\n\nInvalid option! Try again.\n";
			main();
		}
	}

	return 0;
}


Was This Post Helpful? 0
  • +
  • -

#11 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 04:24 PM

Quote

I can't seem to remember any better way to recursively call the main function

That is because you are not allowed to call main recursively in a C++ program, ever. You need to look at some of the other looping constructs like do/while(), while(), for(;;). See this link: Control Structures.

What does the cout on line 138 produce when you run your program? How many lines does your file contain?

Jim

This post has been edited by jimblumberg: 07 February 2012 - 04:25 PM

Was This Post Helpful? 0
  • +
  • -

#12 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 04:32 PM

Number of lines - size displayed as int. Just look at the top of my post: the file contains 5 lines. And my program compiles and functions perfectly - even on those parts where it calls the main() function recursively. But that doesn't matter now.

As I recall, it's the size of the vector.
Was This Post Helpful? 0
  • +
  • -

#13 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: Last element of vector always disappears (C++)

Posted 07 February 2012 - 05:03 PM

And what is it printing to the screen? I doubt that it is reporting 5, I would say it is reporting 6.

Jim

This post has been edited by jimblumberg: 07 February 2012 - 05:03 PM

Was This Post Helpful? 0
  • +
  • -

#14 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 08 February 2012 - 03:07 AM

View Postjimblumberg, on 08 February 2012 - 01:03 AM, said:

And what is it printing to the screen? I doubt that it is reporting 5, I would say it is reporting 6.

Jim


It's reporting 5, as it should.
Was This Post Helpful? 0
  • +
  • -

#15 boris90  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 31
  • Joined: 15-November 09

Re: Last element of vector always disappears (C++)

Posted 08 February 2012 - 05:55 AM

I found a solution to this by myself. Just used this line:

// Get the last element of the vector (product)
// [solution to bug: last element keeps disappearing]
string lastElement = allLines.back();



for getting the last element before another one is updated (which I thought was causing the last one to disappear) and a bit later used this:
// Add the last element of the vector (product) to the end of the vector
// [solution to bug: last element keeps disappearing]
allLines.push_back(lastElement);



to put it back in as a last element in a vector. I even tested this by trying to "buy" the last element and it normally calculated the remaining amount of it and stored it back to a vector. It's working now.

Thanks anyway, Mentor. :gunsmilie:
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2