[Okta Webinar] Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1773
  • 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

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