Как мне найти положение совпадающих круглых или фигурных скобок в текстовом файле ввода на языке c?

Я пишу программу на C .., которая открывает простой текстовый файл, содержащий исходный код типа C, читает его и выводит файл с тем же содержанием, что и первый, за исключением того, что все комментарии удалены. Программа должна проверить, что все скобки совпадают, если они не совпадают, программа должна отобразить сообщение об ошибке с указанием типа ошибки и номера строки, в которой возникла эта ошибка. (Я отображал сообщение об ошибке, но как я могу определить положение ошибки ...?) Входные и выходные файлы передаются программе в #### ой строке параметров, например: ./ваш_исполняемый файл inputfile.txt outputfile.txt

Вот код, который я написал:

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

/* Functions */
void check_comment (char) ;  // checks for both types of comments, then passes on control to below comments
void block_comment () ;   //  handles block or multiline comments
void single_comment () ;   // handles single line comments

/* 2 file pointers - 1st is for the file in which we check for comments,
and 2nd is the file in which we copy the code after removing comments  */
FILE *fp , *fp2;

int main(void)
{
    char c;

    fp = fopen ("inputfile.txt","r") ;   // open the first file in read mode
    fp2 = fopen ("outputfile.txt","w") ;    // open the second file in write mode
    while((c=fgetc(fp))!=EOF)       // read the file character by character
        check_comment(c);   // check for each character if it seems like the beginning of a comment

     //  close both the files at the end of the program
    fclose(fp);
    fclose(fp2);

    FILE *fp;
    char fname[20];
    char brackets[20] = "{}[]()";
    int bracketCounts[6] = {0};
    char * found;
    int i;

    printf("Please enter the destination of the file: \n");
    scanf("%s", fname);

    if ((fp = fopen(fname, "r")) == NULL){
        printf("Problem opening file!\n");
        return 0x00;
    }

    printf("File opened correctly\n");

    // counting various parentheses
    while ((c = getc(fp)) != EOF){
        found = strchr(brackets, c);
        if (found != NULL) {
            bracketCounts[found - brackets]++;
        }
    }

    // dont't forget to close file after reading is done
    fclose(fp);

    // checking parentheses counters
    for (i=0; i < 6; i+=2) {
        if (bracketCounts[i] != bracketCounts[i+1]) {
            printf("Unbalanced parentheses !\n");
            return 0x00;
        }
    }

    printf("All parentheses are OK!\n");

    return 0;
}

// function that handles both types of comments
void check_comment(char c)
{
    char d;

    if ( c == '/')   // if the character starts with '/', it 'could' be a comment
    {
        if ((d=fgetc(fp))=='*')   // if the next character we read is '*', it is the beginning of multiblock comment
            block_comment();  // pass control to function that handles multiblock comments

        else if ( d == '/')   // else if the next character we read is '/', it is the beginning of single line comment
        {
            single_comment();// pass control to function that handles single line comment

        }
        else
        {
            // if both the cases fail, it is not a comment, so we add the character as it is in the new file.
            fputc(c,fp2);
            fputc(d,fp2);
        }
    }

    // again, if all above fails, we add the character as it is in the new file.
    else
        fputc(c,fp2);
}


// function that handles block comments
void block_comment()
{

 char d,e;

    while((d=fgetc(fp))!=EOF)   // the block comment has started, read the character by character
    {
    /* keep reading the characters and do nothing,
    as they do not have to be copied into the new file (we are removing the comments)
    */
        if (d=='*')    // if the comment 'seems' like ending
        {
            e=fgetc(fp);  // check if it actually ends (block comments end with '*/')

            if (e=='/')  // if the comment 'has' ended, return from the function
                return;
        }
   }

}

// function that handles single line comments
void single_comment()
{
 char d,e;

    while((d=fgetc(fp))!=EOF)  // the single line comment has started, read the character by character
    {
    /* keep reading the characters and do nothing,
    as they do not have to be copied into the new file (we are removing the comments)
    */
        if (d=='\n')   // check if the comment ends (single comments end with '\n', or newline)
            return;  // if the comment 'has' ended, return from the function

    }

}
fgetc возвращает int
Antti Haapala 17.12.2018 18:09

Что конкретно ваш вопрос к нам? Мы не являемся службой поддержки широкого профиля: мы ожидаем довольно узких вопросов. См. как спросить.

John Bollinger 17.12.2018 18:27

Номер строки? Нет. Или отсканируйте на предмет отступов.

purec 17.12.2018 18:27

Запустите компилятор! система ("gcc inputfile.txt");

purec 17.12.2018 18:30

я имею в виду, если есть несоответствующие скобки, есть ли способ показать, где ошибка?

Mickey Klau 17.12.2018 18:30

Для параметров командной строки требуется main(int argc, char **argv)

stark 17.12.2018 19:00
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
6
122
1

Ответы 1

вы можете реализовать или использовать структуру данных стека при чтении входного файла, если вы получили { , ( or [, нажав на стек, и если вы получите }, ) or ], вытолкните стек, в конце входного файла стек должен быть пустым, тогда вы получите правильное совпадение, иначе произошло какое-то несоответствие.

вместе с парантезом вы можете сохранить номера строк (или положение и т. д.)

пример: 1 ( 2 (somethig) 3 something),

push (, line1, затем push (, line2 и когда вы получите ) pop (, line2 и так далее, в этом случае, если вы не получите второй закрывающий ), вы можете сказать, что (, line1 отсутствует закрытие.

Почему, если мы можем просто использовать целочисленный счетчик и увеличивать или уменьшать его?

purec 17.12.2018 18:33

Если у нас есть {{...}, как мы можем определить, какой из первых двух не попадает в половину?

purec 17.12.2018 18:40

стек также является своего рода инкрементом (push) и декрементом (pop), но вместе с массивом для извлечения информации о вещах при каждом приращении и уменьшении, эту информацию мы можем использовать в соответствии с требованием

ShivYaragatti 17.12.2018 18:43

@purec: {{ ..} - это случай, явно закрывающийся, потому что первый { - это тот, которого не хватает, если мы нажимаем как {1, {2, когда получаем }, мы выталкиваем `{2` мы оставили один` {1`

ShivYaragatti 17.12.2018 18:46

@ShivYaragatti или для второго ... нет никакого способа выяснить, какой из них на самом деле не хватает закрывающего. По соглашению для отчетности обычно берется первый.

Serge 17.12.2018 19:18

@Serge: Не уверен, почему вы так думаете, со стеком мы можем четко определить, чего здесь не хватает, рассмотрим случай 1) {}{ и 2) {{}, разве мы не можем различить разницу? в первом случае явно закрытие, соответствующее второму открытию {отсутствует, а в случае 2 закрытие, соответствующее первому открытию, отсутствует, поскольку оно вложено. в конце в стеке останется только несоответствие, если мы сохраним номер строки при нажатии на стек, этого достаточно, чтобы указать, для какого открытия отсутствует соответствующее закрытие.

ShivYaragatti 18.12.2018 04:09

Примечание @Serge: для закрытия отсутствует, вы не можете сказать, где он должен закрыться, только мы можем указать строку открытого (, для которого отсутствует соответствующий закрытый ), и таким же образом мы также можем проверить открытие (отсутствует.

ShivYaragatti 18.12.2018 04:09

@ShivYaragatti, мы не знаем наверняка, даже если мы что-то упускаем.

purec 18.12.2018 08:42

Другие вопросы по теме