views:

117

answers:

4

I'm having some problems trying to run this program I am working on...The requirements say I was not allowed to use a sort function...I had do something myself....etc.

Pretty much, the program compiles but hangs after executed...I'm guessing it's stuck in an infinite loop...but I can't seem to find it... :(

This program reads to data files that will already be ordered least to greatest and merges them (ordered) into a third .txt file...

The two files are Data1.txt and Data2.txt contains:

Data1.txt

2
2
2
2

Data2.txt

1
3
5
7
9

combine.c

#include <stdio.h>
#include <stdlib.h>


void sortData(FILE *fpData1, FILE *fpData2)
{

 int n, m; 
 FILE *fpMerge;


 fpMerge = fopen("Merge.txt", "w+");


 fscanf(fpData2, "%i", &n);
 fscanf(fpData1, "%i", &m);
 while(n != EOF || m != EOF)
 {

  if(n == EOF)
  {
   fscanf(fpData1, "%i", &m);

   while(m != EOF)
   {

    fprintf(fpMerge, "%i\n", m);
    fscanf(fpData1, "%i", &m);
   }
  }
  if(m == EOF)
  {
   fscanf(fpData2, "%i", &n);

   while(n != EOF)
   {

    fprintf(fpMerge, "%i\n", n);
    fscanf(fpData2, "%i", &n);
   }

  }

  if(n < m)
  {
   fprintf(fpMerge, "%i\n", n);
   fscanf(fpData2, "%i", &n);
  }
  if(n > m)
  {
   fprintf(fpMerge, "%i\n", m);
   fscanf(fpData1, "%i", &m);
  }
  if(n == m)
  {
   fprintf(fpMerge, "%i\n", n); 
   fprintf(fpMerge, "%i\n", m);
   fscanf(fpData2, "%i", &n);
   fscanf(fpData1, "%i", &m);

  }
 }

 fclose(fpMerge);
}

int main (void)
{
 FILE *fpData1;
 FILE *fpData2;


 fpData1 = fopen("Data1.txt", "r");
 if(fpData1 == NULL)
 {
  printf("There was an error opening the file...program terminating..\n");
  exit(1);
 }

 fpData2 = fopen("Data2.txt", "r");
 if(fpData2 == NULL)
 {
  printf("There was an error opening the file...program terminating..\n");
  exit(1);
 }



 sortData(fpData1, fpData2);


 fclose(fpData1);
 fclose(fpData2); 

 return 0;
}
+7  A: 

You don't want to compare n != EOF, but rather the return value of fscanf:

int count_1;
count_1 = fscanf(fpData1, "%i", &m);
if (count_1 == EOF) // EOF (or error)
{
  // ...
}

fscanf will also return EOF on error. If you need to tell EOF and error conditions apart, use ferror(fpData1), say, and then look up the error code (stored in errno).

Jack Kelly
could i use (!feof(filename)) then? I was using that to begin with...but I tried changing it to != EOF to see if it made a difference... and it didn't..
Bri
My manual pages say nothing about `fscanf()` setting the stream eof flag (the one `feof()` tests). Why not grab the return value and test if it is `EOF`?
Jack Kelly
I figured out my problem.. I hate my loops kind of messed up checking for the wrong EOF. Thanks anyway :)
Bri
A: 

Why algorithm tag is attached to this problem?

Manoj R
A: 

Your testing of EOF is not quite correct

void sortData(FILE *fpData1, FILE *fpData2)
{
    int data1;
    int data2; 
    FILE *fpMerge;

    fpMerge = fopen("Merge.txt", "w+");
    fscanf(fpData1, "%i", &data1);
    fscanf(fpData2, "%i", &data2);

    // While one file still has data        
    while(!feof(fpData1) && !feof(fpData2))
    {
        // Choose 1 file to test
        // Read from that file and put into merge file until either we
        // run out of data or the condition fails.
        if(data1 < data2)
        {
            do {fprintf(fpMerge, "%i\n", data1);}
            while ((fscanf(fpData1, "%i", &data1) != 0) && (data1 <= data2));
        }
        else
        {
            do {fprintf(fpMerge, "%i\n", data2);}
            while ((fscanf(fpData2, "%i", &data2) != 0) && (data2 <= data1));
        }
        // NOTE: if fscanf() returns 0 it has failed to read (EOF)
    }
    // One of the files has reached the EOF
    // Dump the other file.
    while(fscanf(fpData1, "%i", &data1) != 0) {fprintf(fpMerge, "%i\n", data1);}
    while(fscanf(fpData2, "%i", &data2) != 0) {fprintf(fpMerge, "%i\n", data2);}
}
Martin York
+1  A: 
pmg
`EOF` is an integer (or at least convertible to one): it's returned by `int fscanf(FILE *stream, const char *format, ...)`. My copy of `stdio.h` (from eglibc, I think) `#define` s `EOF` as -1. A better statement would be: "If you `fscanf()` into a variable and check that against `EOF`, you're not doing what you think you're doing. You're comparing the value read from the file against whatever your version of `stdio.h` uses to indicate `EOF`, which is almost certainly not what you want."
Jack Kelly
Yes, my text was a bit too strong. Thanks for the correction.
pmg
Yeah... `EOF` is an integer, and `char unsigned` values are a subset of `int` disjoint with the only condition value used in these `f*` stdio functions, `EOF`.
Matt Joiner