CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 3 123 LastLast
Results 1 to 15 of 37
  1. #1
    Join Date
    Nov 2016
    Posts
    32

    Read a line in a file and store in an array C++

    I have an assignment that asks me to read a file in .txt as following:
    "Item: Wood 2.5
    Item: Metal 5.5
    Item: Cat 900
    Item: Spear 50.7
    Recipe: Spear = Wood + Wood + Metal ;"

    I am asked to print out:

    What file to load?
    items1.txt
    Making Wood, profit=0
    Making Metal, profit=0
    Making Cat, profit=0
    Making Spear, profit=40.2
    This means if any item is not included in the recipe, its profit is zero (as the problem defines that way).

    This is just my general approach and I am kinda stuck. Please help me move forward with this thought. Thanks!


    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <sstream>
    
    #include <string>
    using namespace std;
    
    #define max 50;
    
    int main()
    {
    	//int i = 0;
    	//double recipes;
    
    	
    	ifstream in_stream;
    	ofstream out_stream;
    	
    	string fileName;
    	cout << "Enter the file name : ";
    	cin >> fileName;
    	
    	in_stream.open(fileName.c_str());
    	
    	//error checking
    	if (in_stream.fail())
    	{
    		cout << "File could not be opened." << endl;
    		exit(1);
    	}
    	
        int number_of_lines = 0;
        string line;
        while (getline(in_stream, line))
        {   
            ++number_of_lines;
    	} 
    	cout << "Number of lines in text file: " << number_of_lines;
        int a = number_of_lines;
        string items[50];
    	double values[a];
    	
    	while (!in_stream.eof()) 
    	{
    		for(int i = 0; i <= a; i++)
    		{
    			in_stream >> items[i] >> values[i];
    			cout << items[i] << values[i];
    		}
    	}
    	return 0;
    
    }

  2. #2
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    The best container to use for this is a map - as opposed to an array. The index is then the item name and the mapped value is the 'cost' of the item. The program is then essentially as pseudo-code

    Code:
    while (getline(in_stream, line)) {
       //parse line
       if line is item {
          store into map
          display name and profit is 0
       } else {
           If line is Recipe {
              parse line into required item names
              look up name(s) in map and get values
              compute profit/loss
           } else {
              //error!
           }
    }
    See http://www.cplusplus.com/reference/map/map/ re details of map.

    To parse the recipe lines, you might find it useful to convert the string input into a string stream. See http://www.cplusplus.com/reference/s.../stringstream/

    PS I've noticed that this will give two messages for Spear, once for the item line and once for the recipe line. The 'easiest' way is simply to display the message for recipe, but this is not what the question asked! To display as required, with Spear only being displayed once for recipe is not that straightforward. There are a couple of wayd of doing this, but expanding upon the above method, you'll also need to hold in the map whether an item has been used in a recipe and store the recipe profit back into the map for that item. Iterate the map and displaying only items used will display spear only once - but as a map is sorted, the lines won't be in the same order as in the file. Doh! So add a count to the map incremented when an item is added, create a vector from the map sorted by the count and then finally display from the vector - which gives the required output.

    Nice one, professor!
    Last edited by 2kaud; December 2nd, 2016 at 06:01 PM. Reason: PS
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  3. #3
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    Quote Originally Posted by 2kaud View Post
    The best container to use for this is a map - as opposed to an array. The index is then the item name and the mapped value is the 'cost' of the item. The program is then essentially as pseudo-code

    Code:
    while (getline(in_stream, line)) {
       //parse line
       if line is item {
          store into map
          display name and profit is 0
       } else {
           If line is Recipe {
              parse line into required item names
              look up name(s) in map and get values
              compute profit/loss
           } else {
              //error!
           }
    }
    See http://www.cplusplus.com/reference/map/map/ re details of map.

    To parse the recipe lines, you might find it useful to convert the string input into a string stream. See http://www.cplusplus.com/reference/s.../stringstream/

    PS I've noticed that this will give two messages for Spear, once for the item line and once for the recipe line. The 'easiest' way is simply to display the message for recipe, but this is not what the question asked! To display as required, with Spear only being displayed once for recipe is not that straightforward. There are a couple of wayd of doing this, but expanding upon the above method, you'll also need to hold in the map whether an item has been used in a recipe and store the recipe profit back into the map for that item. Iterate the map and displaying only items used will display spear only once - but as a map is sorted, the lines won't be in the same order as in the file. Doh! So add a count to the map incremented when an item is added, create a vector from the map sorted by the count and then finally display from the vector - which gives the required output.

    Nice one, professor!
    Is there any way, without using a map, to input from a file and recognize that oh this line contains the word "Item", then I know I will input these lines. Then if there is also a way to find out a line containing a word oh I found a word recipe, then it will input that line as a recipe. Next step, is there a way to use some functions as find or substring to find if after the "=", there are ingredients that match the items listed above, then it will take the values of money associated with them items to give the total profit for that recipe.
    This is really hard for me...

  4. #4
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    this line contains the word "Item", then I know I will input these lines. Then if there is also a way to find out a line containing a word oh I found a word recipe, then it will input that line as a recipe.
    Use string .find(). See http://www.cplusplus.com/reference/string/string/find/

    is there a way to use some functions as find or substring to find if after the "="
    Can use .find() then .substr() to extract. See http://www.cplusplus.com/reference/s...string/substr/.

    However, it is probably easier to use a stringstream class so that extraction >> can be used. See http://www.cplusplus.com/reference/s.../stringstream/.eg
    Code:
    string s = "qwerty asdfgh";
    stringstream ss(s)
    string q, a;
    ss >> q >> a;
    Is there any way, without using a map,
    Using a map just makes the look up easier. The data record can be stored in an array and searched using find_if() to find the required items for the value. See http://www.cplusplus.com/reference/algorithm/find_if/
    Last edited by 2kaud; December 3rd, 2016 at 06:29 AM.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  5. #5
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    Quote Originally Posted by 2kaud View Post
    Use string .find(). See http://www.cplusplus.com/reference/string/string/find/



    Can use .find() then .substr() to extract. See http://www.cplusplus.com/reference/s...string/substr/.

    However, it is probably easier to use a stringstream class so that extraction >> can be used. See http://www.cplusplus.com/reference/s.../stringstream/.eg
    Code:
    string s = "qwerty asdfgh";
    stringstream ss(s)
    string q, a;
    ss >> q >> a;


    Using a map just makes the look up easier. The data record can be stored in an array and searched using find_if() to find the required items for the value. See http://www.cplusplus.com/reference/algorithm/find_if/
    Hello,
    I am still struggling since I may not think through of searching through date from a file .txt. I totally understand your explanation above about find() and substr() but I only used those before when I am prompted to input a string. Now this gets a bit difficult since I do not input anything by typing. The code will read from a file.

  6. #6
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    I only used those before when I am prompted to input a string. Now this gets a bit difficult since I do not input anything by typing
    Code:
    string line;
    while (getline(in_stream, line))
    {  
       //process line
    }
    line is a string that contains the contents of the line read from the file. As it is a string then the string functions (eg substr) can be used. eg
    Code:
    if (line.substr(0, 5) == "Item:") {
      //Process item line
    }
    or using a string stream
    Code:
    stringstream lss(line);
    string type;
    string name;
    
    lss >> type >> name;
    
    if (type == "Item:") {
      //process item line
    }
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  7. #7
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    Quote Originally Posted by 2kaud View Post
    Code:
    string line;
    while (getline(in_stream, line))
    {  
       //process line
    }
    line is a string that contains the contents of the line read from the file. As it is a string then the string functions (eg substr) can be used. eg
    Code:
    if (line.substr(0, 5) == "Item:") {
      //Process item line
    }
    or using a string stream
    Code:
    stringstream lss(line);
    string type;
    string name;
    
    lss >> type >> name;
    
    if (type == "Item:") {
      //process item line
    }
    Thank you so much. you are a great teacher. I am working on my code now.

  8. #8
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    Quote Originally Posted by 2kaud View Post
    Code:
    string line;
    while (getline(in_stream, line))
    {  
       //process line
    }
    line is a string that contains the contents of the line read from the file. As it is a string then the string functions (eg substr) can be used. eg
    Code:
    if (line.substr(0, 5) == "Item:") {
      //Process item line
    }
    or using a string stream
    Code:
    stringstream lss(line);
    string type;
    string name;
    
    lss >> type >> name;
    
    if (type == "Item:") {
      //process item line
    }
    Item: Wood 2.5
    Item: Metal 5.5
    Item: Cat 900
    Item: Spear 50.7
    Recipe: Spear = Wood + Wood + Metal ;

    Hello, I have some new thoughts about my assignment
    1) I have thought of extracting every single word in the recipe. Why? Because I thought somehow if these extracted words match with the items described above them, meaning from the assignment definition, I have to buy those items to make the recipe, so the profit for them is 0.
    2) Bearing the idea 1), I have tried to extract just the words such as wood, metal, cat, spears and then compare them to the spear recipe. If any of them is included in the recipe, that means we have to buy the items to make them, so the profit is 0.
    3) The next step is to actually calculate the profit from making the recipe. In order to do so, I have to think of a way to extract the number in according to the items included in the recipe. I am quite stuck with that.
    So far, I have this code.
    Code:
    #include <iostream>
    #include <fstream>
    #include <cstdlib>
    #include <sstream>
    #include <string>
    
    using namespace std;
    
    string nextstring(string str, int start_index);
    int split(string str, string a[], int max_size);
    
    int main()
    {	
    	ifstream in_stream;
    	ofstream out_stream;
    	
    	string fileName;
    	cout << "Enter the file name : ";
    	cin >> fileName;
    	
    	in_stream.open(fileName.c_str());
    	
    	//error checking
    	if (in_stream.fail())
    	{
    		cout << "File could not be opened." << endl;
    		exit(1);
    	}
    	
        string lines;
    	while(getline(in_stream, lines))
        {  
    		int eq_pos = lines.find("=");
    		int semi_pos = lines.find(";");
    		int max_size = lines.length();
            if(lines.substr(0,6) == "Recipe" && semi_pos != string::npos)
            {
    			lines.erase(semi_pos);
    			string recipes;
    			recipes = lines.substr(eq_pos+1);
    			string recipe[100];
    			int cnt = split(recipes,recipe,max_size);
    			for (int i=0; i<cnt; i++)
    			{
    				cout << recipe[i] << endl;
    			}
    			if(lines.substr(0,6) == "Item")
    			{
    				items = lines.substr
    					
    		}
    			
    
    	}
    	return 0;
    
    }
    
    string nextstring(string str, int start_index)
    {
    	
    	int y =0;
    	y = str.find('+',start_index);
    	y = y-start_index;
    	str = str.substr(start_index,y);
    	return str;
    	
    }
    
    int split(string str, string a[], int max_size)
    {
    	int i;
    	int num = 0;
    	for (i=0; i<max_size; i++)
    	{
    		
    		a[i] = nextstring(str,num);
    		num = num + a[i].length() + 1;
    		if(num >= str.length())
    		{
    			i++;
    			break;
    		}
    	}
    	
    	return i;
    }
    Thanks

  9. #9
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    You're making things much more complicated than they need to be. The hint given above was to use stringstream. Consider
    Code:
    string lines;
    while(getline(in_stream, lines))
    {
        stringstream lss(lines);
        string type, name;
        lss >> type >> name;
        //We now have type as the type of the line (Item: or  Recipe:) and name as the type name eg Wood or Spear etc
        if (type == "Item:") {
            //Have an item line so need to get item value
            double value;
            lss >> value;
            //Now have name and value so need to store so can be accessed later from Recipe: line
        } else {
           if (type == "Recipe:") {
             //Got a recipe. Know name of recipe from above so need to extract the item names from the line
             string itmnam;
             //Remove the =
             lss >> itmnam;
             //Can check here if this is indeed = otherwise error
             while (lss >> itmnam) {
                 //Got an item name for the recipe. Need to find its value and process. May also be + or ; 
             }
          } else {
                 //Got an error line
          }
       }
    }
    When you get an item line you need to store the value of the name and when you get a recipe line you need to look up the names to find the stored value. As I mentioned earlier, the easiest way to do this is use a map. Consider
    Code:
    map<string, double> mymap;
    
    map["spear"] = 11.11;
    map["wood"] = 34.45;
    map["metal"] = 22.67;
    
    cout << "The value of wood is " << map["wood"] << endl;
    cout << "The value of metal is " << map["metal"] << endl;
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  10. #10
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    I got an error which says "File could not be opened".
    Code:
    #include <sstream>
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {	
    	ifstream in_stream;
    	ofstream out_stream;
    
    	string fileName;
    	cout << "Enter the file name : ";
    	cin >> fileName;
    
    	in_stream.open(fileName.c_str());
    
    	//error checking
    	if (in_stream.fail())
    	{
    		cout << "File could not be opened." << endl;
    		exit(1);
    	}
    	string lines;
    	while(getline(in_stream, lines))
    	{
    		stringstream lss(lines);
    		string type, name;
    		lss >> type >> name;
        //We now have type as the type of the line (Item: or  Recipe:) and name as the type name eg Wood or Spear etc
        if (type == "Item:") 
        {
            //Have an item line so need to get item value
            double value;
            lss >> value;
            //Now have name and value so need to store so can be accessed later from Recipe: line
        }
        else 
        {
           if (type == "Recipe:")
            {
             //Got a recipe. Know name of recipe from above so need to extract the item names from the line
             string itmnam;
             //Remove the =
             lss >> itmnam;
             //Can check here if this is indeed = otherwise error
    			while (lss >> itmnam) 
    			{
                 //Got an item name for the recipe. Need to find its value and process. May also be + or ;
                 if(itmnam == type)
                 {
    				 cout << "No no";
    			} 
    			}
    		} 
    		else 
    		{
                 cout << "Making no profit";
    		}
        }
    	}
    }

  11. #11
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    usually I would open a file like this
    Code:
    	string inam;
    	cout << "Enter file name: ";
    	cin >> inam;
    
    	ifstream ifs(inam);
    
    	if (!ifs.is_open()) {
    		cout << "Cannot open input file " << inam << endl;
    		return 1;
    	}
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  12. #12
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    File still could not be opened. Interesting. Maybe something wrong with my string stream command? Do i have to close() at the end even though I am not outputting anything to a file? Please help me.
    Code:
    string fileName;
    	cout << "Enter the file name : ";
    	cin >> fileName;
    
    	ifstream in_stream(fileName);
    
    	//error checking
    	if (!in_stream.is_open())
    	{
    		cout << "File could not be opened." << endl;
    		return 1;
    	}
    	string lines;
    	
    	while(getline(in_stream, lines))
    	{
    		stringstream lss(lines);
    		string type, name;
    		lss >> type >> name;
        //We now have type as the type of the line (Item: or  Recipe:) and name as the type name eg Wood or Spear etc
        if (type == "Item:") 
        {
            //Have an item line so need to get item value
            double value;
            lss >> value;
            //Now have name and value so need to store so can be accessed later from Recipe: line
        }
        else 
        {
           if (type == "Recipe:")
            {
             //Got a recipe. Know name of recipe from above so need to extract the item names from the line
             string itmnam;
             //Remove the =
             lss >> itmnam;
             //Can check here if this is indeed = otherwise error
    			while (lss >> itmnam) 
    			{
                 //Got an item name for the recipe. Need to find its value and process. May also be + or ;
    				if(itmnam == type)
    				{
    				 cout << "No no";
    				} 
    			}
    		 } 
    		else 
    		{
                 cout << "Making no profit";
    		}
        }
    	}

  13. #13
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    If the filename specified can be not be opened, then there is a problem with the file - the program hasn't got to the string stream part at that point. Is the file located in the same folder as the program? If not, are you specifying the correct path to the file? Does the file actually exist - and be opened by another program (eg notepad etc)? Myself, for testing purposes I usually hard code file name(s) as a const string at the top of the program. eg
    Code:
    const string fileName = "items.txt";
    Then the first 3 lines of the code in post #12 can be commented out.

    IMO, however, I would suggest that before you continue to try to develop the program as you code that you take a step back and first produce a program design and only when you are happy with the design do you then start to code the program from the design.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

  14. #14
    Join Date
    Nov 2016
    Posts
    32

    Re: Read a line in a file and store in an array C++

    Hi,
    how do I parse "Recipe: Spear = Wood + Wood + Metal ;" into an array[] of just {Spear, Wood, Wood, Metal } without using vector since I am not allowed to use that in my assignment. Thanks!

  15. #15
    2kaud's Avatar
    2kaud is offline Super Moderator Power Poster
    Join Date
    Dec 2012
    Location
    England
    Posts
    7,825

    Re: Read a line in a file and store in an array C++

    without using vector since I am not allowed to use that in my assignment
    Tell your professor that (s)he should be teaching you how to use c++ properly!

    Why do you want to parse the recipe line into an array? There is no need to do this. Have a variable that holds the recipe name and then for each of the items found that make up the recipe look them up in the array that has been constructed from the item: lines.

    If you are going to use an array to hold the item names and values rather than the easier map, then you'll need a struct something like
    Code:
    struct record {
       string name;
       double value;
    };
    then define an array of record
    Code:
    const int maxrec = 20;
    record items[maxrec];
    
    int itmpos = 0;
    Then in the code for item:

    Code:
    items[itmpos].name = name;
    items[itmpos++].value = value;
    So when you get an item name for recipe, you scan the array looking for the name and when found you get the associated stored value.
    All advice is offered in good faith only. All my code is tested (unless stated explicitly otherwise) with the latest version of Microsoft Visual Studio (using the supported features of the latest standard) and is offered as examples only - not as production quality. I cannot offer advice regarding any other c/c++ compiler/IDE or incompatibilities with VS. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/ and can be used without reference or acknowledgement. Also note that I only provide advice and guidance via the forums - and not via private messages!

    C++23 Compiler: Microsoft VS2022 (17.6.5)

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured