Okay, so the premise is that this place contains items for sale, and has five of everything that it sells. The inventory is brought in from a file and with parallel arrays you set up the item names with the inventory in stock. I have that all down, but now I need to get a cin loop going which I'm not sure how to do and if the user enters an item name that's in the array, the stock for that item is decremented one. My current troubles aside from not sure how to get a cin loop going, is that I can't even figure out how to let the user enter a string and see if it matches any of the item names in the array. Here's the code I have written:

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>

using namespace std;

const int MAX_ITEMS = 1000;
string filename;
string names [MAX_ITEMS];
int inventory [MAX_ITEMS];
string item;
string item2;
int count;
int count2 = 0;
int inventorycount = 5;
int main()
{
  ifstream inFile;
  cout << " ** 5-of-Everything Department Store ** " << endl;
  cout << "What's the inventory file?" << endl;
  getline(cin, filename);
  inFile.open(filename.c_str());
  count = 0;
getline(inFile, item);
  while (inFile)
  {
   names[count] = item;
   count++;
   inventory[count2] = inventorycount;
   count2 ++;
   getline(inFile, item);
  }
  inFile.close();
  cout << "What is being sold?" << endl;
  cin >> item2;
  if (item2 == names[count])
        {
        cout <<"Sold!" << endl;
        }
  else
        {
        cout <<"Sorry not in stock!"<< endl;
        }
return 0;
}

I'm not sure what to be comparing after something has been entered from the user, to check if that item name exists in the array. Also the user is supposed to be allowed to enter the item name in all lowers even though in the inventory file it may be spelled with capital letters. I've been messing around with tolower, but it says it expects an int where I've tried to use a string. So, not sure how to do a tolower on a string, of if it's even possible.

I got the cin loop going with a do while loop, not sure if that was the best route to take with it but it works. My main and biggest confusion is allowing the user to enter a name of an item, checking if it's in the array, and not caring if its all lower or whatever they may type.

To compare your strings, ignoring any case difference, you should first of all change the strings to all upper case or all lower case after reading them in, such as:

transform(names[count]begin(), names[count].end(),names[count].begin(), toupper);

Use tolower as the last parameter if you want lower case.

Do this to the data you read in to the array, and to the item2 string. Then your equality test will work reliably.

Ensure that you add #included <cctype> to your code.


Alternatively, if your compiler supports it, you could use the c-style string comparison function that ignores case:

if( stricmp( names[count].c_str(  ),   item2.c_str( )  ) == 0 )  //they match

The c_str() method of the string class give a c-style equivalent of the string (actually a pointer to char array) so that the older compare function can be used.

As you read in an item to be purchased, you will have to compare it to every item name in your array, until a match is found or you exceed count locations. Then check the parallel index location in the inventory array for a non-zero count.

If you will be doing many purchase transactions, it might be worthwhile to sort the array of strings before begining purchases. Simple linear search can then stop when you've gone past the point of finding a match, or better yet, use Binary Search.

Val

>transform(names[count]begin(), names[count].end(),names[count].begin(), toupper);
Good idea, unsound implementation. The problem is that toupper is overloaded and your compiler may create an ambiguity behind the scenes. On top of that, even if your compiler does the right thing and picks the C toupper, the behavior is still undefined because transform expects a function or function object with C++ linkage, and the C toupper is explicitly declared with C linkage. This is better:

#include <cctype>

struct upper {
  int operator() ( int c ) {
    return std::toupper ( static_cast<unsigned char> ( c ) );
  }
};

...

std::transform ( src.begin(), src.end(), src.begin(), upper() );

>Alternatively, if your compiler supports it, you could use the c-style string comparison function that ignores case:
A better way would be to hide it behind a macro (or function) so that you don't lose portability:

#define compare_insensitive stricmp

...

if( compare_insensitive( names[count].c_str(  ),   item2.c_str( )  ) == 0 )  //they match

Or write your own comparison function, because it's not difficult at all.

Thanks for the help everybody, I have solved the comparing two strings part as well as converting the inputted string to all upper case. Two problems down, yet two remain. For some reason I need help with an else statement, you'll see it in the code, I'll highlight it. And somehow I need to keep track of how much of each item has sold, so that at the end I can output that to the user with the item name, only if it's actually sold at all, if it didn't then ignore it. Anyway here's the updated code as it stands.

#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <cctype>
using namespace std;

const int MAX_ITEMS = 50;
string filename;
string names [MAX_ITEMS];
int inventory [MAX_ITEMS];
string item;
string item2;
int i;
int inventorysales = 0;
char d;
int s;
int inventorycount = 5;
int itemssold;


int main()
{
  int count;
int count2 = 0;
  int i;
  ifstream inFile;
  cout << " ** 5-of-Everything Department Store ** " << endl;
  cout << "What's the inventory file?" << endl;
  getline(cin, filename);
  inFile.open(filename.c_str());
  count = 0;
  getline(inFile, item);
  while (inFile)
{
   names[count] = item;
   count++;
   inventory[count2] = inventorycount;
   count2 ++;
   getline(inFile, item);
  }
  cout << "What is being sold? If nothing, type q to quit" << endl;
  getline (cin, item2);
  while (item2 != "q")
{
        for (int s=0; s<item2.length(); ++s)
        {
        item2[s]=toupper(item2[s]);
        }

        for (i =0; i < count; ++i)
        {
        if (item2 == names[i] && inventory[i] != 0){
   cout <<"Sold!" << endl;
                        inventory[i] = inventory[i] - 1;}

        }
   //   else if (item2 != names[i])
//              cout << "Sorry out of stock!" << endl;

    cout << "What is being sold? If nothing, type q to quit" << endl;
    getline (cin, item2);
  }
cout << "Sales Report         " << "(item / count sold)" << endl;





  return 0;
}

The stuff in red is what I want to be output if the item never appears in the array or if its stock of 5 has depleted, but for some reason it has a problem with me trying to put an else statement or an else if even in that for loop along with the if statement there already. Not sure why that is. And then I've messed around with how to calculate a running total of sales, but I can't think of how to mess with the array side of things once again, I tried doing something but it had some compiling error that I was doing too many things in the array.

I'd set up the test and decision code like:

bool found = false; //add this to your variable declarations

       found = false;
       for (i =0; i < count && !found; ++i)
        {
               if (item2 == names[i] )    //is there a matching item
               {
                    found = true;             //lets us stop short when found item
                    if inventory[i] != 0){   //if so, are any in stock?
                        cout <<"Sold!" << endl;
                        inventory[i] = inventory[i] - 1; }
                    else
                        cout << "Sorry out of stock!" << endl;
                }

        }
        if( !found ) //ran all the way through   
              cout << "no such item in list" << endl;
This article has been dead for over six months. Start a new discussion instead.