8 Replies - 1335 Views - Last Post: 31 August 2011 - 04:30 AM Rate Topic: -----

#1 Squiddles  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 29-September 09

File I/O with columns and multidimensional array

Posted 29 August 2011 - 10:27 PM

So I can safely say I can get I/O from a single-lined text file and store it in an array.

Single-lined text file:
Bob
79
98
34
98
75



Code that does said task:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main(int argc, char *argv[])
{
    ifstream inData ("grades.txt");
    ofstream outData;
    
    int position=0;
    int size=0;
    string grades[6];
    int total=0;
    string line;
    
    if(inData.is_open())
    {
         while(!inData.eof())
         {
              getline(inData, line);
              grades[position]=line;
              cout<<grades[position]<<endl;
              position++;
         }
         inData.close();
    }
    else
         cout<<"Unable to open file"<<endl;
}



I'm struggling to find a clear answer on how to get accurate input, and storage into a multidimensional array, with a text file that's organized as such:
Bob	Joe	Steve	Jon	Mary
75	81	81	65	98
98	78	86	90	21
34	56	78	87	54
98	53	86	98	98
75	98	98	98	98


(There are tabs between each column if that's important)

I have a feeling I'd need the use of a nested for-loop structure, but the separation of the lines is what confuses me the most.

This post has been edited by Squiddles: 29 August 2011 - 10:31 PM


Is This A Good Question/Topic? 0
  • +

Replies To: File I/O with columns and multidimensional array

#2 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 02:42 AM

If the data was arranged like this:
Bob 22 56 41, 39
Alice 44 55 38
etc.,
you'd use:
for(row = 0; row < maxRows; row++) {
  fscanf(fp, "%s", name[row]);
  for(col = 0; col < maxCols; col++) {
    fscanf(fp, "%d", &score[row][col];
  }
}


To change to column oriented format (what you showed), just read the name, and then vary the *row* in the inner for loop, instead of the column:

for(col = 0; col < maxCols; col++) {
  fscanf(same as above)
  for(row = 0; row < maxRows; row++) {  //increment each inner loop by a row, not by a col
    fscanf(same as above];
  }
}



I'm guessing you are using parallel arrays of char names[][] and int scores[][]. If you're using an array of structs, the particulars change, but the idea is the same.

After you get all the data into your two arrays, the printing is the same as normal - left to right, top to bottom, and tab between each score you print out. include ('\t') in the print call.

This post has been edited by Adak: 30 August 2011 - 02:47 AM

Was This Post Helpful? 0
  • +
  • -

#3 Salem_c  Icon User is offline

  • void main'ers are DOOMED
  • member icon

Reputation: 1578
  • View blog
  • Posts: 3,004
  • Joined: 30-May 10

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 03:23 AM

What about a C++ answer Adak?
Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg  Icon User is offline

  • member icon


Reputation: 3845
  • View blog
  • Posts: 11,753
  • Joined: 25-December 09

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 05:23 AM

First a couple of observations about your "working" program. One you should always check that your file open succeeded. Two using eof() for reading the file will produce one extra line of text, because eof() does not fail until after it tries to read past the end of file. Lastly you are reading your "numbers" into a std::string which you will need to convert to numbers. You could be reading the file and placing the variables directly into int variables. Also since you are using a while loop you should be checking to insure that you do not try to read in more variables than your array will hold. Otherwise you may be accessing the array out of bounds.

Now as to how to read a line of multiple entries separated by the tab character you have several ways to proceed.

One way is to setup a couple of loops to read the data one value at a time into an int variable with the stream extraction operator>>. The stream extraction operator will by default stop when it encounters a whitespace characters.

Another way is similar to the way you got the data in your "working" program. Use a couple of loops and use getline() to get the individual data from each line. You would use getline() with the optional third parameter, the delimiter. Like: getline(yourStream, yourString, '\t').

I would suggest that you investigate vectors to replace your arrays.


Jim

This post has been edited by jimblumberg: 30 August 2011 - 05:24 AM

Was This Post Helpful? 1
  • +
  • -

#5 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5643
  • View blog
  • Posts: 12,359
  • Joined: 16-October 07

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 05:48 AM

I'm missing something; where does Bob get read from the file? Why the hell is grades an array of string? If you reach position 6, do you stop?

I'd make a struct, with a char array for name and an int array for grades. I'd then just do binary read writes. It's least effort for me, the programmer.

However, if you must read from a text file, then horizontal, as noted, is the way to go. I'd read the line as a string, then parse it.

Again, you do NOT have a 2D array problem. It's a struct problem. Do not use 2D arrays of string just to mash mismatched crap together.
Was This Post Helpful? 1
  • +
  • -

#6 Squiddles  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 6
  • Joined: 29-September 09

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 06:17 PM

View Postbaavgai, on 30 August 2011 - 06:48 AM, said:

I'm missing something; where does Bob get read from the file? Why the hell is grades an array of string? If you reach position 6, do you stop?

I'd make a struct, with a char array for name and an int array for grades. I'd then just do binary read writes. It's least effort for me, the programmer.

However, if you must read from a text file, then horizontal, as noted, is the way to go. I'd read the line as a string, then parse it.

Again, you do NOT have a 2D array problem. It's a struct problem. Do not use 2D arrays of string just to mash mismatched crap together.


A struct? I'm sorry, I'm a bit new at C++. I know the issue isn't a 2D array, just it's a part of what's being used in this.

As for an explanation of type mixing, read below. Now that you mention it, I am interested in separating the strings from the integers, but one problem at a time! Haha.

View Postjimblumberg, on 30 August 2011 - 06:23 AM, said:

First a couple of observations about your "working" program. One you should always check that your file open succeeded. Two using eof() for reading the file will produce one extra line of text, because eof() does not fail until after it tries to read past the end of file. Lastly you are reading your "numbers" into a std::string which you will need to convert to numbers. You could be reading the file and placing the variables directly into int variables. Also since you are using a while loop you should be checking to insure that you do not try to read in more variables than your array will hold. Otherwise you may be accessing the array out of bounds.

Now as to how to read a line of multiple entries separated by the tab character you have several ways to proceed.

One way is to setup a couple of loops to read the data one value at a time into an int variable with the stream extraction operator>>. The stream extraction operator will by default stop when it encounters a whitespace characters.

Another way is similar to the way you got the data in your "working" program. Use a couple of loops and use getline() to get the individual data from each line. You would use getline() with the optional third parameter, the delimiter. Like: getline(yourStream, yourString, '\t').

I would suggest that you investigate vectors to replace your arrays.


Jim

I thought I was checking if it was open with the if statement? And what should I be doing instead of eof? As for the numbers, I'm aware they're being read as strings. When I first wrote this I had the strings being converted 'on the fly' with:
grades[position]=atoi(line.c_str());


When I originally had the array setup as an integer type. I have to admit, I'm not sure how the line works past the equal sign. I then decided to go a bit further than that and incorporate names into the mix. My plan is to read the columns into the array, list the names which should be the first position in each 'dimension', read/convert the numbers into the integer "total" and get the average of said numbers.

I can change the text file to have the names in beginning of each row if that would be easier.

I was also thinking of using vectors for this, but I figured I'd tackle that after I get the text parsing out of the way.
Was This Post Helpful? 0
  • +
  • -

#7 #define  Icon User is offline

  • Duke of Err
  • member icon

Reputation: 1276
  • View blog
  • Posts: 4,400
  • Joined: 19-February 09

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 06:48 PM

You can create a two-dimensional array.
Lets say with room for a maximum of 12 people.

string grades[12][6];

grades[0][0] = "Bob";
grades[0][1] = "79";
grades[0][2] = "98";
grades[0][3] = "34";
grades[0][4] = "98";
grades[0][5] = "75";

grades[1][0] = "Joe";
grades[1][1] = "81";
grades[1][2] = "78";
...


Was This Post Helpful? 0
  • +
  • -

#8 Adak  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 331
  • View blog
  • Posts: 1,168
  • Joined: 01-April 11

Re: File I/O with columns and multidimensional array

Posted 30 August 2011 - 08:36 PM

View PostSalem_c, on 30 August 2011 - 03:23 AM, said:

What about a C++ answer Adak?


My C++ stopped with Turbo C++. The only C compiler I have set up now, is Pelles C (which has no C++ option).

I thought the C code would help the OP. If not, I'll refrain from answering the C++ questions. I may get back into C++, but right now I'm learning the Google language, Go.
Was This Post Helpful? 0
  • +
  • -

#9 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon

Reputation: 5643
  • View blog
  • Posts: 12,359
  • Joined: 16-October 07

Re: File I/O with columns and multidimensional array

Posted 31 August 2011 - 04:30 AM

Your basic element has a string, name, and five integers? So:
const int GradeCount = 5;
struct StudentGrade {
	string name;
	int grades[GradeCount];
};



To read the data from a stream, you'd normally do something like:
void read(istream &in, StudentGrade &g) {
	in >> g.name;
	for(int i=0; i<GradeCount; i++) {
		in >> g.grades[i];
	}
}



You may use the read above to load a record from cin or an open ifstream. I've probably given too much and it may be going over your head, for which I'm sorry, but that's how you'd usually attack such a problem. 2D arrays make sense in a limited number of applications, and never with mixed types. In C++, a struct or class is your fundamental element of complex storage.

Hope this helps.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1