views:

1355

answers:

4

I'm trying to collect information from a textfile which contains names of organisations (without spaces) and floating integers. I want to store this information in an array structure.

The problem I'm having so far is collecting the information. Here is a sample of the textfile:

CBA 12.3 4.5 7.5 2.9 4.1

TLS 3.9 1 8.6 12.8 4.9

I can have up to 128 different numbers for each organisation, and up to 200 organisations in the textfile.

This is what my structure looks like so far:

struct callCentre
{
char name[256];
float data[20];
};

My main:

int main()
{
callCentre aCentre[10];
getdata(aCentre);
calcdata(aCentre);
printdata(aCentre);
return 0;
}

And the getdata function:

void getdata(callCentre aCentre[])
{
ifstream ins;
char dataset[20];

cout << "Enter the name of the data file: ";
cin >> dataset;

ins.open(dataset);

if(ins.good())
{
 while(ins.good())
 {
  ins >> aCentre[c].name;
  for(int i = 0; i < MAX; i++)
  {
   ins >> aCentre[c].data[i];
   if(ins == '\n')
    break;
  }
  c++;
 }
}
else
{
 cout << "Data files couldnt be found." << endl;
}
ins.close();
}

What I'm trying to achieve in my getdata function is this: store the organisation name first into the structure, then read each float into the data array until the program detects a newline byte. However, so far my check for the newline byte isn't working.

Assume that variables c and MAX are already defined.

How should I go about this properly?

+3  A: 

The >> operator treats whitespace as a delimiter, and that includes newlines, so it just eats those and you never see them.

Rubendv
Not true, it will eat up everything until the whitespace character, the next time thereafter when you call it, it will skip over the whitespace character up until it reaches another whitespace character."hello there"Will result in hello being eaten, and " there" still being around.
X-Istence
Cont. using .peek() you can then check out what the next character is in line.
X-Istence
@X-Istence with "eat up" I meant they were skipped and you didn't get to see them. Two uses of >> on "hello \n there" results in "hello" and "there", right?
Rubendv
+1  A: 
char byte = ins.peek();

Or

if(ins.peek() == '\n') break;

(Edit): You'll want to also check for an eof after your peek(), because some files may not have a ending newline.

I'd like to point out that you might want to consider using a vector<callCentre> instead of a static array. If your input file length exceeds the capacity of the array, you'll walk all over the stack.

greyfade
This did exactly what I wanted. Thank you.
tmhai
+3  A: 

You need to read lines and then chop the lines up. The following bit of hackery illustrates the basic idea:

#include <iostream>
#include <string>
#include <sstream>
using namespace std;

int main() {
    string line;
    while( getline( cin, line ) ) {
     istringstream is( line );
     string cs;
     is >> cs;
     double vals[10];
     int i = 0;
     while( is >> vals[i] ) {
      i++;
     }

     cout << "CS: " << cs;
     for ( int j = 0; j < i; j++ ) {
      cout << " " << vals[j];
     }
     cout << endl;
    }
}
anon
I tried implementing this. Good idea though.
tmhai
+2  A: 

I would read the file, one line after another and parse each line individually for the values:

std::string line;
while (std::getline(ins, line)) {
  std::istringstream sline(line);
  sline >> aCentre[c].name;
  int i = 0;
  while (sline >> aCentre[c].data[i])
    i++;
  c++;
}
sth