Reading Contents from Text to Arrays?

So I have a question about reading input from a text file that is structured in the following manner: (Text file has a total of 30 lines, 6 provided for template)

Red
Apple
12
Blue
Sky
14
+26 more lines following the order of color/object/number


I have three parallel arrays created
char[][color]
char[][object]
double[]

I would like the text file values to be assigned to their appropriate array
so
char[][color] would contain Red, Blue, Yellow etc
char[][object] would contain Apple, Sky, Taxi etc
double[] would contain 12, 14, 20 etc


I'm actually not sure how to even go about this?

Would I use a

while (fin.getline(?,?))
{fin.getline(?,?}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  void read_combo(char[][color], char[][object], double[])
{
	ifstream fin;
	fin.open("C:\\Temp\\combo.txt");							
	
	if (!fin)
	{
		cout << "Cannot open combo.txt" << endl;
		exit(1);
	}

	
	



	fin.close();        
}
Last edited on
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::strings?

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.
Wow, this definitely helped. You put a lot of work on this, I really appreciate your work. Certain things I haven't learned about so gotta brush up on those subjects.
Topic archived. No new replies allowed.