Ben Zifkin
Ben Zifkin

Reputation: 952

building a very simple parser in C

I'm trying to build a very simple parser in C for a class. All it has to do is read in a flag from an input file, determine if the flag precedes an int, char, or float and then write int/float/char to the appropriate .txt file. for example I 9898 would be printed to int.txt. Whenever use the testing script the instructor provided i get these errors:

parser.c:1:1: error: unknown type name ‘e’ parser.c:1:10: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘on’ parser.c:1:10: error: unknown type name ‘on’

This is my code please let me know. Thanks so much:

int main(int argc, char *argv[])
{
#include <stdio.h>
    FILE *input = fopen("input.txt", "r");
    FILE *ints.txt = fopen("ints.txt" "w");
    FILE *chars.txt = fopen("chars.txt", "w");
    FILE *floats.txt = fopen("floats.txt", "w");

    char flag;
    int ipint;
    char ipchar;
    float ipfloat;
    int exitStatus = fscanf(input.txt, "%c", &flag);

    while (exitStatus != EOF)
    {
        if (flag == I)
        {
            fscanf(input.txt, "%i", &ipint);
            fprintf(ints.txt, ipint);
        }
        if (flag == C)
        {
            fscanf(input.txt, "%c", &ipchar);
            fprintf(chars.txt, ipchar);
        }
        if (flag == F)
        {
            fscanf(input.txt, "%f", &ipfloat);
            fprintf(floats.txt, ipfloat);
        }
    }
    fclose(input.txt);
    fclose(ints.txt);
    fclose(floats.txt);
    fclose(chars.txt);
}

Upvotes: 2

Views: 36285

Answers (3)

paulsm4
paulsm4

Reputation: 121649

Suggested changes:

#include <stdio.h>

int main(int argc, char *argv[])
{
    FILE fp_input = NULL;
    FILE fp_ints = NULL;
    FILE fp_chars = NULL;
    FILE fp_floats = NULL;

    char flag;
    int ipint;
    char ipchar;
    float ipfloat;
    int exitStatus;

    if (!(fp_input= fopen("input.txt", "r")) {
      perror ("fp_input failed");
      return 1;
    }

    if (!(fp_ints = fopen("ints.txt" "w")) {
      ...
    if (fscanf(fp_input, "%c", &flag)!= 1) { 
      ...

    while (exitStatus != EOF){
      switch (flag) {
        case 'I' :
          fscanf(fp_input,"%i",&ipint);
          fprintf(fp_ints, "%d", ipint);
          break;
        case 'C' :
          ...
        default :
          ...
    }

In other words:

1) The #include is in the wrong place

2) I would not use variable names like input.txt with a period in the name.

3) I think you meant constant 'I' instead of the variable I

4) You should check for errors whenever/wherever possible (like fopen, fscanf, etc)

5) You need a format string for your fprintf()

Upvotes: 3

smac89
smac89

Reputation: 43078

  • Use switch statements rather than multiple if

while (exitStatus != EOF)
{
    switch (flag) {

        case 'I':
            //...
            break;

        case 'C':
            //...
            break;

        case 'F':
            //...
            break;

        default:
            puts("Flag not recognized");
            return EXIT_FAILURE;
        }
}
  • fprintf is the same as printf and only difference is that you get to decide stdout, so character formatting is still required
  • Variable names cannot have . character in them as this is reserved for accessing members of an object
  • exitStatus needs to be updated at each iteration so that the program will know when to stop reading from the file. I used fgetc and ungetc for that

This code should do what you need:

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

int main(int argc, char *argv[])
{
    FILE *input = fopen("input.txt", "r");
    FILE *ints = fopen("ints.txt", "w+");
    FILE *chars = fopen("chars.txt", "w+");
    FILE *floats = fopen("floats.txt", "w+");

    int flag, ipint, exitStatus;
    char ipchar;
    float ipfloat;

    if (NULL == input) {
        perror("File not found [input.txt]");
        return EXIT_FAILURE;
    }

    while ((exitStatus = fgetc(input)) != EOF && ungetc(exitStatus, input))
    {
        fscanf(input, "%d", &flag);
        switch (flag) {

            case 'I':
                fscanf(input, "%i", &ipint);
                fprintf(ints, "%i", ipint);
                break;

            case 'C':
                fscanf(input, "%c", &ipchar);
                fprintf(chars, "%c", ipchar);

                break;

            case 'F':
                fscanf(input, "%f", &ipfloat);
                fprintf(floats, "%f", ipfloat);
                break;

            default:
                puts("Flag not recognized");
                fclose(input);
                fclose(ints);
                fclose(floats);
                fclose(chars);
                return EXIT_FAILURE;
        }

    }
    fclose(input);
    fclose(ints);
    fclose(floats);
    fclose(chars);

    return EXIT_SUCCESS;
}

Upvotes: 0

ouah
ouah

Reputation: 145829

Put the standard headers at file scope, not a block scope:

 #include <stdio.h>

 int main(int argc, char *argv[])
 {
    ...

Upvotes: 5

Related Questions