在C中构建一个非常简单的解析器

时间:2013-09-22 21:26:42

标签: c parsing

我正在尝试在C中为类构建一个非常简单的解析器。它所要做的只是从输入文件中读取一个标志,确定该标志是否在int,char或float之前,然后将int / float / char写入相应的.txt文件。例如,我将9898打印到int.txt。每当使用测试脚本时,教师提供的这些错误都会出现:

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’

这是我的代码,请告诉我。非常感谢:

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);
}

3 个答案:

答案 0 :(得分:4)

将标准标题放在文件范围内,而不是块范围:

 #include <stdio.h>

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

答案 1 :(得分:3)

建议的更改:

#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 :
          ...
    }

换句话说:

1)#include位于错误的地方

2)我不会使用名称为input.txt的变量名称。

3)我认为你的意思是'I'而不是变量I

4)您应该随时/尽可能地检查错误(例如fopenfscanf等)

5)您需要fprintf()

的格式字符串

答案 2 :(得分:1)

  • 使用switch语句而不是多个if

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

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

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

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

        default:
            puts("Flag not recognized");
            return EXIT_FAILURE;
        }
}
  • fprintfprintf相同,唯一的区别在于您决定stdout,因此仍然需要进行字符格式设置
  • 变量名称中不能包含.个字符,因为这是为访问对象的成员而保留的
  • exitStatus需要在每次迭代时更新,以便程序知道何时停止从文件中读取。我使用fgetcungetc作为

此代码应该满足您的需求:

#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;
}