【问题标题】:How to read two consecutive characters from a file in C?如何从C中的文件中读取两个连续的字符?
【发布时间】:2014-03-16 21:30:22
【问题描述】:

我有以下代码,我想为简单的计算器语言创建一个简单的扫描仪。我正在使用 fgetc 从文件中获取字符。不过,在某些地方,我还需要检查后面的下一个字符。出于这个原因,我一直在使用 ++ 运算符,但它似乎无法正常工作。谁能帮我解决我的问题。

例如,当我的文本文件中有 := 时,它会打印冒号,然后显示一条错误消息:“; cannot follow : (colon).”,而它应该打印“assign”。

这是我的完整代码:

#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>

int main(int argc, char** argv)
{
    FILE *fp;
    int c, check, reti_d, reti_l;

    regex_t digit, letter;
    reti_d = regcomp(&digit, "[0-9]", 0);
    reti_l = regcomp(&letter, "[a-zA-Z]", 0);

    if (reti_d || reti_l)
    {
        fprintf(stderr, "Couldn't compile the regular expression(s).\n");
        exit(1);
    }

    if (argc != 2)
    {
        fprintf(stderr, "Usage: %s filename.txt\n", argv[0]);
        exit(1);
    }

    if (!(fp = fopen(argv[1], "r")))
    {
        perror("Error opening file!\n");
        exit(1);
    }

    while ((c = fgetc(fp)) != EOF)
    {
        char regdtest[1];
        char regltest[1];
        regdtest[0] = (char)c;
        reti_d = regexec(&digit, regdtest, 0, NULL, 0);
        reti_l = regexec(&letter, regltest, 0, NULL, 0);

        switch (c)
        {
            case '(': printf("lperen "); break;
            case ')': printf("rparen "); break;
            case '+': printf("plus "); break;
            case '-': printf("minus "); break;
            case '*': printf("times "); break;
        }

        if (c == ':')
        {
            if (c++ == '=')
                printf("assign ");
            else printf("\n%c cannot follow : (colon).\n", (char)c);
        }

        if (c == '/')
        {
            if (++c == '/' || ++c == '*')
            {
                while (c != '\n' || (c == '*' && ++c == '/'))
                    c++;
            }
            else printf("div ");
        }

        if (c == '.')
        {
            regdtest[0] = (char)++c;
            reti_d = regexec(&digit, regdtest, 0, NULL, 0);

            if (!reti_d)
            {
                printf("number ");
            }
            else printf("\n. (dot) should be followed by digits.\n");
        }

        if (!reti_d)
        {
            while (!reti_d)
            {
                regdtest[0] = (char)c;
                reti_d = regexec(&digit, regdtest, 0, NULL, 0);
            }

            printf("number ");
        }

        if (!reti_l)
        {
            int i, j = 0;
            char read[5], write[6];
            read[i] = write[j] = (char)c;

            while(!reti_d || !reti_l)
            {
                c++;
                i++;
                j++;

                if (i >= 5)
                    i = 0;
                if (j >= 6)
                    j = 0;

                read[i] = write[j] = (char)c;
                if (strcmp(read, "read") == 0)
                    printf("read ");
                else printf("id ");

                if (strcmp(write, "write") == 0)
                    printf("write ");
                else printf("id ");

                regdtest[0] = (char)c;
                regltest[0] = (char)c;
                reti_d = regexec(&digit, regdtest, 0, NULL, 0);
                reti_l = regexec(&letter, regltest, 0, NULL, 0);
            }

            printf("letter ");
        }

    }

    fclose(fp);
    return 0;
}

【问题讨论】:

    标签: c file fgetc getc


    【解决方案1】:

    您需要再次调用fgetc() 来获取第二个字符。

    【讨论】:

    • 你的意思是在我有 ++ 运算符的每个地方,我都需要更改为 fgetc() 函数调用?
    • 有点。我认为最简单的方法是有两个变量:c1c2。阅读c1 后,如果您决定需要以下字符,请阅读c2 并从那里建立您的逻辑。
    • c++ 表示增加c 的值。您的变量 c 没有“历史记忆”,它对文件或文件的来源一无所知。要从文件中获取另一个字符,您必须实际告诉编译器您要从文件中获取一个字符,例如fgetc.
    【解决方案2】:

    按照@pmg 的建议,将++c 替换为fgetc()

    下面是重新设计的if (c == '/') 部分。各种语法错误路径未完全编码,下面可能需要额外的代码来处理意外路径。请记住,任何fgetc() 都可能导致 EOF 条件。此外,在 fgetc() 撤消调用之间最多可以执行 1 个 ungetc()

    if (c == '/') {
      c = fgetc(fp);
      if (c == '/') {
        c = fgetc(fp);
        if (c == '*') {
          while (c = fgetc(fp) != '\n' && c != EOF) {
            if (c == '*') {
              c = fgetc(fp);
              if (c == '/') break;
              ungetc(c, fp);
            }
          }
          printf("div ");
        }
        else TBD();
      } else ...
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-06
      • 1970-01-01
      • 2016-11-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多