• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1775
  • Last Modified:

Do while statement will not terminate at EOF

I am trying to read input from a file specified on the command line and put it into a stack. This works, but it doesn't terminate the while statement when EOF is reached. Also, I am trying to read double values from a file and put them on a stack. I know how to put integers, but not doubles. Thanks Alot!



/*---------------------------------------------------------------------------  
//
//  Given a file of infix expressions, this program will convert the    
//  expression to postfix and evaluate it. Also, this program will terminate
//  on bad data. Before conversion, it will check the data for extra spaces
//  and uneven parentheses.
//---------------------------------------------------------------------------*/

#include <stdlib.h>
#include <stdio.h>
#include "Stack.h"
//#include "infixpost.h"
int main(int argcount , char *argvec[])
{
    FILE * in;
    //FILE * outfile;
    //int c;
    //double val;
    //int iterations;
      //Stack Input;
    //Stack copypost;
    Stack temp;
    char b;
      //StackEntry item;
      
    //Stack copyinput;
    //Stack Outfix;
    //StackEntry a;
    //iterations = 0;

      if(argcount !=3)
            printf("You must supply a file name to process and on to write too\n");
      else
      {      
        puts("Getting file size");  
            in = fopen(argvec[1],"r");
        //outfile = fopen(argvec[2], "w");
        if(in == NULL)
        Error("Cannot open file for reading");

    }
    //CreateStack(&Outfix);
    //CreateStack(&Input);
    //CreateStack (&copyinput);
    //CreateStack (&copypost);
    CreateStack(&temp);

    do
    {
        while (b= (fgetc(in)!= '\n'))
        {
            Push(b, &temp);
        }
   
    printf("in do while loop\n");
   
      /*while(!StackEmpty(&temp))
               {      
        Pop(&item, &temp);
            Push(item,&Input);
      }*/
   
        /*voidspace(&Input);
        StackCopy(&copyinput, &Input);
        BracketCheck(&copyinput, &c);
        if(c == 1)
        {
           
            InfixToPostfix(&Input, &Outfix);
            StackCopy(&copypost, &Outfix);
            Value(&Outfix, &val);    
            print(&copyinput, &copypost, outfile);
            printf("%lg", val);
            iterations++;
        }
        else
        {
            printf("\n\n***Error- Unbalanced Parentheses***");
        }

        ClearStack(&Outfix);
        ClearStack(&Input);
        ClearStack(&copyinput);
        ClearStack (&copypost);


        printf("\n%d ITERATIONS HAVE BEEN EVALUATED\n\n", iterations);
        //fprintf(outfile," %d EXPRESSIONS HAVE BEEN EVALUATED\n\n", iterations);
                if(b == EOF)
            fclose(in);*/

    }while(b !=EOF);
    return;
}

0
mwinfiel
Asked:
mwinfiel
  • 2
  • 2
  • 2
  • +1
1 Solution
 
Khanh DoanSenior DeveloperCommented:
   }while(b !=EOF);
    return;
}
Change to

    }while(eof(b));
    return;
}

From Borland C Help:
/* reads chars from the file until it reaches EOF */
do
{
   read(handle, &ch, 1);
   printf("%c", ch);
} while (!eof(handle));
Bonmat86.
0
 
Khanh DoanSenior DeveloperCommented:
oops, i mean
Change to

    }while(!eof(b));
    return;
}
Bonmat86.
0
 
mwinfielAuthor Commented:
eof() is not a function in the C standard library feof() is but that doesn't work either.
0
Improve Your Query Performance Tuning

In this FREE six-day email course, you'll learn from Janis Griffin, Database Performance Evangelist. She'll teach 12 steps that you can use to optimize your queries as much as possible and see measurable results in your work. Get started today!

 
Kent OlsenData Warehouse Architect / DBACommented:

Hi mwinfiel,

One of the issues that you may be running into is that EOF isn't set just because the file pointer is positioned at the end of the file.  EOF is set when you try to read after reaching the end.  Consider the following example

File d contains one line:

ABCDEF<newline>

Reading the file via fgets() will read the entire line into a buffer and position the file pointer past the <newline> character.  It will NOT set EOF.  You therefore know that it's OK to process the data that you read.

When the program loops back and tries to read again, the I/O system detects that the pointer is at end-of-file, sets EOF, and returns NULL (or zero).

You're calling fgetc() instead of fgets(), but the same principal applies.  EOF being NOT set means that you read valid data.  The do/while loop will actually read the file one more time than you expect and attempt to process the EOF character (-1) as data.

A simpler approach is to change the do/while and then test for eof after each read.

        while (b= (fgetc(in)!= '\n'))
        {
          if (b = (char)EOF)
            break;
          Push(b, &temp);
        }

// or

        while (b= (fgetc(in)!= '\n'))
        {
          if (feof (in))
            break;
          Push(b, &temp);
        }

Note that this inner loop should be followed by a test that the stack is not empty.  EOF could be reached with valid data on the stack if the last line of the file is not terminated with a new-line.



Good Luck,
Kent

0
 
mwinfielAuthor Commented:
OMG it works!! Thanks Alot Kent. So do you have any idea how I would read in double values and put that on the stack? I have an idea.... I thinkg as long as the value was a number or '.', I would put it into a char array and then put the whole array on one stack slot. But, I can't seem to put the whole array on one stack slot
0
 
Kent OlsenData Warehouse Architect / DBACommented:

Well, if it were me, I'd read an entire line at a time and parse it instead of reading one character at a time.  Here's a sketch of the code:



  int  I;
  double D;
  int  Decimal;

  while (1)
  {
    fgets (buffer, buffersize, in);
    if (feof (in))
      break;

    I = 0;
    D = 0;
    Decimal = 0;
    for (ch = buffer; *ch && *ch != '\n'; ++ch)
    {
      if (isdigit (*ch))
        if (Decimal)  // process fractional part
        ....
        else
        {
          I = I * 10 + (*ch - '0');
          D = D * 10 + (*ch - '0');
        }
      else if (*ch == '.')
        if (Decimal)   // Second decimal point.  Handle it somehow
        else
          Decimal = true;
      else
      {
        if (Decimal)
          PushDecimal (D);
        else
          PushInteger (I);
      }
    }
  }
0
 
brettmjohnsonCommented:
>         while (b= (fgetc(in)!= '\n'))
>         {
>           Push(b, &temp);
>         }

I could not help but notice the oddly grouped parenthesis.  
The code, as is, pushes true or false on the stack [technically 0 or non-0].  It is pushing the result of the comparison between the character fetched and newline.  [Actually, it will never push 0 on the stack, because the while() condition will terminate the loop before doing so.]

I think you want:

        while ((b = fgetc(in)) != '\n')
        {
          Push(b, &temp);
        }


0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Turn Raw Data into a Real Career

There’s a growing demand for qualified analysts who can make sense of Big Data. With an MS in Data Analytics, you can become the data mining, management, mapping, and munging expert that today’s leading corporations desperately need.

  • 2
  • 2
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now