You have several issues; I'll take them in order of use:
argument types
What you have declares an argument of "unnamed array of array of chars" where the number of chars is 'color' or 'object'. Use typedefs.
1 2 3 4 5
|
constexpr COLOR_NAME_MAX_LEN = 20;
typedef char ColorName[COLOR_NAME_MAX_LEN];
constexpr OBJECT_NAME_MAX_LEN = 20;
typedef char ObjectName[OBJECT_NAME_MAX_LEN];
|
Now you can use them to make your life so much easier:
void read_combo(ColorName colors[], ObjectName objects[], double numbers[])
Further questions:
- How big are the arrays?
- How do we know?
- How many items do we actually put into the arrays?
- How does the caller know?
C++ Strings
Since this is C++, why are you not using
std::string
s?
void read_combo(std::string colors[], std::string objects[], double numbers[])
Structs
While you are at it, why not stick all this stuff in a
struct
?
1 2 3 4 5 6
|
struct Item
{
std::string color;
std::string object;
double count;
};
|
|
void read_combo(Item items[])
|
C++ Vectors
You can get rid of the last array using vectors:
void read_combo(std::vector<Item>& items)
Why does it matter?
The problem with arrays is you have to be very careful not to put too many things in them.
For example, "Deep Green-Cyan Turquoise" and "Light Cornflower Blue" are both longer than nineteen-characters + null-terminator. Your code will have to be able to
1 stop reading at 19 characters
2 skip the remaining characters
The same holds for the larger array(s). How many items are there to store? Are you sure your array(s) are big enough to hold them all? With a vector, you don't actually have to care.
Now, on to reading methods.
Reading fixed arrays
This is the most difficult way to do it. We need to modify it to track how many.
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
|
bool read_combo(ColorName colors[], ObjectName objects[], double numbers[], int max_items, int& number_of_items_read)
// Reads color,object,number into the argument arrays.
// Argument arrays have maximum length max_items
// Number of items read returned in number_of_items_read
// Returns true if read did not fail at some point.
// (If number_of_items_read == max_items, you have no idea if the entire file was read.)
{
number_of_items_read = 0;
ifstream fin("C:/Temp/combo.txt");
if (!fin) return;
while (number_of_items_read < max_items)
{
if (!fin.getline(colors[number_of_items_read], COLOR_NAME_MAX_LEN))
{
if (fin.eof()) return true; // EOF -- no more items
fin.ignore(numeric_limits<streamsize>::max(), '\n'); // not eof, skip remainder of line
}
if (!fin.getline(objects[number_of_items_read], OBJECT_NAME_MAX_LEN))
{
if (fin.eof()) return false; // EOF -- error
fin.ignore(numeric_limits<streamsize>::max(), '\n'); // not eof, skip remainder of line
}
if (!(fin >> numbers[number_of_items_read))
{
return false;
}
fin.ignore(numeric_limits<streamsize>::max(), '\n'); // skip remainder of line
// Successfully read the next item; update to next index in arrays
number_of_items_read += 1;
}
return true;
}
|
At this point you should be thinking "holy crap!". And this function is still deficient in a number of ways. (Are there more items to read from the file?)
Using C++ vector of struct containing strings
Life is so much easier when C++ manages the arrays for you.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
// This code is broken up into two parts.
// Part 1: read a single Item
istream& operator >> ( istream& ins, Item& item )
{
ins.getline( item.color ); // Read an entire line as color
ins.getline( item.object ); // Read an entire line as object name
ins >> item.count >> ws; // Read an entire line as number + whitespace
return ins; // (Any errors will be returned with the argument stream)
}
// Part 2: read a whole bunch of items
bool read_combo(std::vector<Item>& items)
// Returns whether or not the read failed at some point
{
ifstream fin("C:/Temp/combo.txt");
if (!fin) return false;
Item item;
while (fin >> item)
items.push_back( item );
return fin.eof(); // Successful if we reached EOF
}
|
Now your main():
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
int main()
constexpr NUM_ITEMS = 100;
ColorName colors[NUM_ITEMS];
ObjectName objects[NUM_ITEMS];
double numbers[NUM_ITEMS];
int count;
if (!read_combo(colors, objects, numbers, NUM_ITEMS, count))
{
cout << "fooey!\n";
return 1;
}
cout << "I managed to read " << count << " items. (But there may be more.)\n";
|
1 2 3 4 5 6 7 8 9 10 11 12
|
int main()
{
vector<Item> items;
if (!read_combo(items))
{
cout << "fooey!\n";
return 1;
}
cout << "There are " << items.size() << " items.\n";
}
|
Whew. Hope this helps.