Как прочитать два последовательных символа из файла в C?
У меня есть следующий код, где я хочу создать простой сканер для простого языка калькулятора. Я использую fgetc, чтобы получить символ из файла. Хотя в некоторых местах мне также нужно проверить следующий символ, который следует. По этой причине я использовал оператор ++, но кажется, что он не работает должным образом. Может кто-нибудь помочь мне решить мою проблему.
Например, когда у меня есть:= в моем текстовом файле, он печатает двоеточие, а затем выводит сообщение об ошибке, говорящее: ";
Вот мой полный код:
#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;
}
2 ответа
Как предложил @pmg, замените ++c на fgetc()
,
Ниже переделан if (c == '/')
раздел. Различные пути синтаксических ошибок не были полностью закодированы, и ниже может потребоваться дополнительный код для обработки неожиданных путей. Помни чем нибудь fgetc()
может привести к состоянию EOF. Также до 1 ungetc()
может быть выполнен между fgetc()
призывает отменить.
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 ...