Link to home
Start Free TrialLog in
Avatar of Devante
Devante

asked on

I/O file reading

if i have a record file called in.data with a last name and a first name then 10 integers everything separated by space; for example,
John Doe 30 90 34 45 76 87 45 78 98 76
Bob Davis 78 45 78 89 78 85 95 78 97 79
and so...

how can i read in.data file, then calculate the average of the 10 integers and put the output to a file called out.data; for example,
John Doe 65.9
Bob Davis 80.2
 
Avatar of Exceter
Exceter
Flag of United States of America image

Homework?

Hint: Simply use the in stream operators. For example,

char name[25];
in >> name;

You read in integers the same way. As to the math, well, I'm sure you can figure that out as it is not very difficult to do once you have read in the integers. :-)

Exceter
Avatar of Intern
Intern

Just like Exceter said....  

Use a loop that terminates when

while(!in.eof())


Then I am sure you can figure out how to do the average all by yourself.
Use the stream operators and store each line of data in an array, which needs to be in a master array that holds them all. Intern has a great idea with the loop, which will allow you to create a new element in the master array each time you repeat if you declare it dynamically, unless you know how many lines you will have each time. Then you have all the data, and for the output, you can calculate the average and store it in the 13th slot of the array. Then you can output the first, second, and 13th elements for your output file.
>> while(!in.eof())

It's simpler to say,

while( in )

Exceter
Avatar of Devante

ASKER

i did do that but i keep getting the wrong average... here is my code:

void average(ifstream& in_stream, ofstream& out_stream)
{
  int sum = 0;
  char next;
  double ave = 0.0;
 
 
  in_stream.get(next);
  cout << "First Next: " << next << endl;
 
  while(!in_stream.eof())
    {
      cout << "before if next: " << next << endl;
      if(isdigit(next)){
     if(isspace(next))
       {
       }
     else
       {
         
         cout << "Next after if: " << next << endl;
         sum = sum + next;
         cout << "Sum : " << sum << endl;  
         cout << "Sec Next: " << next << endl;
       }
      }
      else
     out_stream << next;
      in_stream.get(next);
      cout << "Third Next: " << next << endl;
    }
 
  ave =  sum / QUIZ_AVE;
 
  out_stream.setf(ios::fixed);
  out_stream.setf(ios::showpoint);
  out_stream.precision(2);
 
  out_stream << ave;
}
The easiest way to do it would probably be:

// creating streams;
ifstream in.open("in.dat");
ofstream out.open("out.dat");

// variables
char a[25];
int b, avg, x;

// while not end of file
while (in >> a)
{
  avg=b=0; // resets vars
  // loops for 10 numbers adding each to avg
  for (x=0;x<10;x++, avg+=b)
    in >> b; // gets number
  // outputs results
  out << a << ' ' << float(b)/10.0 << endl;
}

// closing streams
in.close();
out.close();
Avatar of Devante

ASKER

I still can not get the right output.  Here is my complit code and the in.dat file is:
John Doe 30 90 34 45 76 87 45 78 98 76
Bob Davis 78 45 78 89 78 85 95 78 97 79
Suzy Thomes 76 78 45 98 87 83 63 94 78 89

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cstring>

using namespace std;

const double QUIZ_AVE = 10.0;

void average(ifstream& in_stream, ofstream& out_stream);

int main()
{
  ifstream fin;
  ofstream fout;

  cout << "Begin editing files.\n";

  fin.open("in.dat");

  if(fin.fail())
    {
      cout << "Input file opening failed.\n";
      exit(1);
    }
  fout.open("out.dat");
  if(fout.fail())
    {
      cout << "Output file opening failed.\n";
     exit(1);
    }

  average(fin, fout);

  fin.close( );
  fout.close( );

  cout << "End of editing files.\n";
  return 0;
}

void average(ifstream& in_stream, ofstream& out_stream)
{
  int b = 0, x, tempNext = 0;
  char next;
  double avg = 0.0;
 
  in_stream.get(next);

  while(!in_stream.eof())
    {

      if(isdigit(next))
     {
       if(!isspace(next))
         {
           if(next != '\n')
          {
            (int)next;
            avg = (int)next;
            for (x=0;x<10;x++, avg+=tempNext)
              {                
                in_stream.get(next);
                (int)next;
              }
           
            out_stream.setf(ios::fixed);
            out_stream.setf(ios::showpoint);
            out_stream.precision(2);
            out_stream << next << float(avg) /10.0 << endl;
          }
         }
     }
      else
     out_stream << next;
     
      in_stream.get(next);
    }
}
>> I still can not get the right output.

I don't doubt it. :-)

You are making this WAY harder thatn it needs to be. You are reading the data one char at a time. This forces you to do all sorts of other tasks to get the correct results. Why bother? Just let the computer take care of that. You can read in one line of data as follows,

char first[25], last[25];
int num[10];

in >> first >> last >> num[0] >> num[1] >> num[2] >> num[3]... etc.

Place this into a while loop like this one,

while( in )
{
}

or something similar. It is then a simple matter to average the values and display the results.

Exceter
Avatar of Devante

ASKER

hey Exceter,
   i did what u told me to do but i get a wired number and also it does not read all the recored; it only reads the first line... here is what i did:
void average(ifstream& in_stream, ofstream& out_stream)
{
  int sum = 0;
  int num[10];
  char first[25], last[25];
  double avg = 0.0;
 
 
  while(in_stream)
    {
      in_stream >> first >> last >> num[0] >> num[1] >> num[2] >> num[3]
          >> num[4] >> num[5] >> num[6] >> num[7] >> num[8]
          >> num[9] >> num[10];
 sum = num[0] +  num[1] + num[2] + num[3] + num[4] + num[5] + num[6]
    + num[7] + num[8] +  num[9] +  num[10];
   
    }
 
  avg = sum / 10.0
     
  out_stream << first << last << avg << endl;
}
ASKER CERTIFIED SOLUTION
Avatar of Exceter
Exceter
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Ugly, ugly code...  Read a line of input, and tokenize it.  Any of the tokens that consist of simply numbers can be made into a number and averaged.  My advice is to make your code accomplish your goals as easy as possible, and no harder.
brian
>>Ugly, ugly code...  

Before putting people down maybe you should realize that this is a place for learning and teaching.  You are not doing any teaching by commenting on how bad things are, but not showing the correct solution.

The only reson I am saying something is that you have posted similar responses in other places.  Things would be better if you restrict yourself to helpful comments, instead of putting people down.


Intern
>> Ugly, ugly code...

Yes it is, but it is also simpler to explain how to fix this without getting into tokenizing.


FYI, bkrahmer flaming is a direct violation of the EE membership agreement, even if what you say is on the mild side. Please restrict yourself to constructive and helpful comments in the future.


Exceter
I'm sorry for 'flaming' Exceter.  I have a low tolerance for teaching newbies incredibly bad habits.  Telling somebody to do cin >> a >> b >> c >> ...  pretty much defeats the point of structured programming, much less OOP.  Don't you think the intention the excercise was to use something like a for loop?  The solution given looks ugly to me, and that is simply aesthetics.  Is is also very unextensible and won't even attempt to give corrent output if there is a value missing on the input.  There is correct code, and then there is robust code.  BTW, tokenizing is a simple concept to me.  See strtok.  
brian
>>BTW, tokenizing is a simple concept to me.  

Have you realized that maybe this is the first class of C++ that this person may be taking.  Tokenizing is easy for me or Exceter to understand but not a newbie.
bkrahmer

Please join us at https://www.experts-exchange.com/questions/20532287/Expert-should-be-warned.html for a quick chat.

** Mindphaser - Community Support Moderator **
Avatar of Devante

ASKER

hey Exceter,
   thanks a lot for your help man, and bkrahmer don't respond to a posting if u don't have the answer [edited by moderator Mindphaser]
Avatar of Devante

ASKER

all i have to say is thank you and you are the man with the master plan
You are most welcome.
Devante

It seems I should invite YOU also to our discussion about language!