Author Topic: More File I/O  (Read 5806 times)

louiecerv

  • Moderator
  • User
  • *****
  • Posts: 85
More File I/O
« on: February 08, 2006, 01:59:57 PM »
A recent example discussed in class involved having to read a file several times, looking for specific value in an input file containing a sorted list of numbers.  As discussed in a previous topic, every time a file is opened, it starts over at the beginning.  This behaviour permits us to write a function that opens a file and reads from the begnning up to a cetain location, thus retrieve the value then closes the file.  The method is not efficient but it serves to demonstrate this particular functionality.

The find median function provides a means to get the median value from a sorted list of numbers using the function getValueAt().  Note that future topics, such as arrays will allow us to design a more efficient algorithm.


Code: [Select]

float findMedian()
{
     ifstream fin;
     fin.open("numlist.txt");
     int next, count=0;
     
     while(fin>> next)
     {
          cout << next << endl;
          count++;
     }
     fin.close();
     
     float median;
     if (count%2 == 0)
     {
         int midnum = count/2;
         median = ( getValueAt(midnum) + getValueAt(midnum + 1) )/2.0;
                           
     } else
     {
         median = getValueAt( ceil(count/2.0) );
     }
     
     return median;
}

int getValueAt(int n)
{
    ifstream fin;
     fin.open("numlist.txt");
     int next;
     for (int i=0;i<n;i++)
     {
         fin >> next;
     }
     fin.close();  
     return next;
}

Analyze. Design. Develop. Debug. Deploy. Maintain.

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
More File I/O
« Reply #1 on: February 08, 2006, 11:48:33 PM »
What about using tellg and seekg?
Gillius
Gillius's Programming http://www.gillius.org/

louiecerv

  • Moderator
  • User
  • *****
  • Posts: 85
using an array to find the median
« Reply #2 on: February 09, 2006, 05:58:49 PM »
We can reduce the read operation to only once if we use an array.

Code: [Select]


float findMedian()
{
     const int ENTRIES = 100;  //maximum entries expected
     int pos[ENTRIES];  
   
     ifstream fin;
     // determine number of entries    
     fin.open("numlist.txt");
     int next, count=0;
     while( fin >> next )
     {
          pos[count] = next;
          cout << next << endl;
          count++;
     }      
     fin.close();
     
     cout << "count = " << count << endl;
     
     float median;
     int midnum = count/2;
     median = pos[midnum];
     
     if (count%2 == 0)
     {
         median += pos[midnum+1];
     }      
     
     return median;
}
Analyze. Design. Develop. Debug. Deploy. Maintain.

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
More File I/O
« Reply #3 on: February 10, 2006, 10:05:01 AM »
OK, I realize now what you are doing, and why tellg and seekg is not actually feasible in this situtation.

When you calculate the median, do you not want to average the two middle numbers?  Currently this program just adds them.

However, this second program is bothersome.  I realize that perhaps the class has not gotten to std::vector or dynamic allocation, but there does need to be some handling in case the count is too large.  It could be just a simple if statement if the file larger than 100 is not allowed.  One could write a numlist.txt file that takes over the program using a buffer overrun.  Also, if the file size is zero or does not exist then the program will return pos[0] + pos[1], neither of which are initalized.

Sorry if I sound overly pedantic here, but I believe that problems like this should at least be acknowledged at some point, even if not handled, because there are typically no classes that ever addresses these issues to make programmers think pessimistically.
Gillius
Gillius's Programming http://www.gillius.org/

Gillius

  • Administrator
  • User
  • *****
  • Posts: 147
    • http://www.gillius.org/
More File I/O
« Reply #4 on: February 10, 2006, 11:17:35 PM »
OK, maybe that was a little harsh to say...  Although I do think it is good to mention some limitations or problems at times with these types of examples.
Gillius
Gillius's Programming http://www.gillius.org/

louiecerv

  • Moderator
  • User
  • *****
  • Posts: 85
More File I/O
« Reply #5 on: February 11, 2006, 12:05:42 PM »
Quote from: "Gillius"
... I do think it is good to mention some limitations or problems at times with these types of examples.


Thanks Jason for pointing out the error.  The last program sample should get the average of the middle numbers:

Code: [Select]

     if (count%2 == 0)
     {
         median = (median + pos[midnum+1])/2.0;
     }  


I acknowledge this sample program was overly simplified and did not provide proper error handling.  To me, you've made an important point that programmers should constantly anticipate sources of errors and beginners should develop this habit of hardening their code with proper error handling sooner rather than later.
Analyze. Design. Develop. Debug. Deploy. Maintain.