Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.86/35: Рейтинг темы: голосов - 35, средняя оценка - 4.86
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
1

Удаление комментариев

26.11.2017, 22:46. Просмотров 6902. Ответов 15
Метки нет (Все метки)


Здравствуйте!
Пишу программу для удаления комментариев из программ. Вот кусочек кода.
Проблема такая: при удалении комментариев вида /**/ остаётся последний /
Подскажите, пожалуйста, как это исправить.


C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
for (i = 0; i < N; i++)
        {
            if (inm[i] == '/')
            {
                if (inm[i + 1] == '*')
                {
                    while ((inm[i] != '*') && (inm[i + 1] != '/'))
                    {
                        inm[i] = 0;
                        inm[i + 1] = 0;
                        i++;
                    }
                }
 
                else if (inm[i + 1] == '/')
                {
                    while (inm[i] != '\n')
                    {
                        inm[i] = 0;
                        i++;
                    }
                }
            }
        }
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
26.11.2017, 22:46
Ответы с готовыми решениями:

Удаление комментариев из текста
вот написал прогу, которая убирает комментарий из текста в стиле /*... */ но есть 1 но, если в 1...

Удаление комментариев из файла
есть набросок функции, которая удаляет из файла все комментарии(с поддержкой многострочности.)....

Удаление комментариев в программном коде Си
Удаление комментариев В языке Си комментарии к исходному коду начинаются с двух символов /* и...

Удаление всех комментариев из программного кода на С
Условие: напишите программу для удаления всех комментраиев из программы на С. Так же нужно...

15
280 / 215 / 98
Регистрация: 11.08.2016
Сообщений: 759
26.11.2017, 23:19 2
У вас на 10 строке в цикле while идёт проверка на текущий символ "звёздочка" и следующий символ "косой слэш".
Дело в том, что когда вы оказались в конце коментария:
C
1
/*comm*/
текущим символом всегда будет 0(кроме первого раза) т.к. мы его затираем в предыдущем шаге этого цикла, а как только встретится последний символ "косой слэш", цикл прекратится и затёрто ничего не будет. После чего произойдёт инкремент переменной i и текущий символ станет как раз "косой слэш" , следующий станет - '\n'. По условию первого if мы войдём в тело, но дальше ничего не сделаем и сразу выйдем от туда. Затем снова инкремент переменной i и т.п.
Надеюсь, вы разберётесь
1
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
27.11.2017, 23:43  [ТС] 3
А в итоге как это исправить?

Добавлено через 4 минуты
Цитата Сообщение от D3m1an Посмотреть сообщение
текущим символом всегда будет 0(кроме первого раза) т.к. мы его затираем в предыдущем шаге этого цикла, а как только встретится последний символ "косой слэш", цикл прекратится и затёрто ничего не будет. После чего произойдёт инкремент переменной i и текущий символ станет как раз "косой слэш" , следующий станет - '\n'. По условию первого if мы войдём в тело, но дальше ничего не сделаем и сразу выйдем от туда.
А как исправить цикл, чтобы правильно удалять комментарии?
0
280 / 215 / 98
Регистрация: 11.08.2016
Сообщений: 759
27.11.2017, 23:54 4
ALexAlexAlexAle, попробуйте просто "дотереть" за циклом :
C
7
8
9
10
11
12
while ((inm[i] != '*') && (inm[i + 1] != '/'))
                    {
                        inm[i] = 0;
                        inm[i + 1] = 0;
                        i++;
                    }
Поставив после него строку " inm[i + 1] = 0;:
C
7
8
9
10
11
12
13
while ((inm[i] != '*') && (inm[i + 1] != '/'))
                    {
                        inm[i] = 0;
                        inm[i + 1] = 0;
                        i++;
                    }
                    inm[i + 1] = 0;
По итогу, логика такова, что после цикла из которого мы выходим когда следующий символ == ' /'. Затем сразу его удалим и все. Выполнение этой строки невозможно без выполнения цикла. Это нам будут гарантировать if'ы выше.
1
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
28.11.2017, 20:37  [ТС] 5
Спасибо большое!
Эта проблема решена.
Теперь появилась новая - Необработанное исключение по адресу 0x008C2037 в Project118.exe: Код инструментирования RangeChecks обнаружил обращение к массиву по индексу, выходящему за его пределы.
Подскажите, в чём может быть дело?

Добавлено через 25 минут
Исправила вот так
for (i = 0; i < sizeof(inm[N]); i++)
Но теперь программа ничего не делает.

Добавлено через 45 минут
Мне нужно из исходного файла удалить комментарии и вывести чистый код в новый файл.
Я вывожу в консоль текст из файла ДО и ПОСЛЕ.
Сейчас они одинаковые.

Добавлено через 30 минут
Неправильно объяснила.
Вывожу текст ДО.
Вывожу текст ПОСЛЕ.
Записываю текст ПОСЛЕ в новый файл.
И эти тексты одинаковые сейчас, т.е. прога не работает и я не понимаю почему.
Хотя работала почти правильно.
Что-то , видимо, написала не то.
0
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
11.12.2017, 20:53  [ТС] 6
Здравствуйте!
Пишу программу по удалению комментариев из кода.
На вход - текстовый файл с кодом с комментариями.
На выходе должен быть чистый код (без комментариев).

В исходном текстовом файле такой текст
'не коммент'
"не коммент"
"//не коммент"
"/*не коммент*/"
"не"коммент"
'не ко"ммент'

//коммент
/*коммент*/
//коммент\
тоже
//коммент\\
тоже

В новый файл должен записаться только первый блок (6 строчек), а получается, вот что: кроме того, что в новый файл копируется ВСЁ, так ещё и в эта строчка
'не ко"ммент'
записывается вот так
'не ко""ммент'



Думаю, что проблема в этом куске кода

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
int flag_start_s = 0; // "
    int flag_start_S = 0; // '
    int spec = 0;
    char c;
    in = fopen("C:\\Users\\ тут адрес\\input.txt", "r");
    out = fopen("C:\\Users\\ тут адрес \\output.txt", "w");
 
    
while ((c = fgetc(in)) != EOF) 
    {
        if (flag_start_s) 
        {
            if (c == '\\')
            {
                kov = !kov;
            }
            else 
                if (c == '"' && !kov) 
                {
                    flag_start_s = 0;
                }
                else
                {
                    kov = 0;
                }
 
            fputc(c, out);
            continue;
        }
 
        if (c == '"')
 
        {
            flag_start_s = 1; 
            fputc(c, out);
        }
 
        if (flag_start_S) 
        {
            if (c == '\\')
            {
                kov = !kov;
            }
            else 
                if (c == '\'' && !kov)
                {
                    flag_start_S = 0;
                }
                else
                {
                    kov = 0;
                }
 
            fputc(c, out);
            continue;
        }
 
        if (c == '\'')
        {
            flag_start_S = 1;
            fputc(c, out);
        }
 
        if ((flag_start_s == 0) && (flag_start_S == 0)) identify_comment(c); 
    }

PS В identify_comment(c) определяем к какому типу комментария относится данный комментарий.

Подскажите, пожалуйста, как это исправить?
0
174 / 138 / 105
Регистрация: 14.04.2016
Сообщений: 735
11.12.2017, 21:05 7
Я чёрт знает что вы там написали, так как без тэга поймут только избранные. В общем читаем построчно. Если два первых строки - "//", или "/*" то это комментарий. В чём тут проблема то?
0
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
13.12.2017, 22:10  [ТС] 8
SlavaSokolov, ладно, а как поставить условия, чтобы вот это не удалялось?

"sadf//sd"
"sdf/*sdf*/sdf"
0
174 / 138 / 105
Регистрация: 14.04.2016
Сообщений: 735
13.12.2017, 22:26 9
Лучший ответ Сообщение было отмечено ALexAlexAlexAle как решение

Решение

ALexAlexAlexAle, берём переменную, которая будет выполнять роль флага. Считываем посимвольно, пропуская области комментариев. Вообще если строка в кавычках, то ничего удалятся не должно, так как это строка и внутри неё не может быть комментариев?
0
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
13.12.2017, 22:29  [ТС] 10
SlavaSokolov, я и хочу, чтобы внутри кавычек не удалялось.
Вы говорите "это строка и внутри неё не может быть комментариев" . Если, например, мне нужно вывести это на экран, то мне нужно будет написать это в принтф. В кавычках.
0
174 / 138 / 105
Регистрация: 14.04.2016
Сообщений: 735
13.12.2017, 23:13 11
ALexAlexAlexAle, набросал на скорую руку. Правда тут надо обработку вложенных элементов добавить...
В таком случае: 1321323/*324234234*/423424*/234324. Будет работать неправильно.
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#define _CRT_SECURE_NO_WARNINGS
 
#include <stdio.h>
 
#define size 256
 
int main()
{
    char array[size];
    scanf("%s", array);
 
    int is_com = 0;
    int len = 0;
 
    for (; array[len] != '\0';)
        len++;
    
    for (int i = 0; array[i + 1] != '\0' && array[i] != '\0' && i < len; i++)
    {
        if (array[i] == '/' && array[i + 1] == '/')
            is_com = 1;
        if (array[i] == '/' && array[i + 1] == '*')
            is_com = 2;
 
        while (is_com == 1 && array[i] != '\0')
        {
            i++;
        }
 
        if (is_com == 2)
        {
            i += 2;
            while (array[i] != '*' && array[i + 1] != '/')
                i++;
            i += 2;
        }
 
        is_com = 0;
        printf("%c", array[i]);
    }
 
    printf("\n");
 
    system("pause");
    return 0;
}
1
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
13.12.2017, 23:56  [ТС] 12
SlavaSokolov, Большое спасибо! Но у меня удаление комментов проходит нормально. Единственная трудность в том, что из двойных кавычек тоже удаляется, хотя я вводила как вы писали флаг. И не могу это исправить.
0
940 / 680 / 225
Регистрация: 30.06.2015
Сообщений: 3,635
Записей в блоге: 37
14.12.2017, 13:29 13
Цитата Сообщение от ALexAlexAlexAle Посмотреть сообщение
файл копируется ВСЁ, так ещё и в эта строчка
'не ко"ммент'
А такая строчка('не ко"ммент') корректна с точки зрения синтаксиса языка си? По моему, на вход программы которая удаляет комментарии нужно подавать заведомо корректный листинг с точки зрения языка. Или будем отлавливать ВСЕ ошибки, которые и так отлавливает компилятор?
0
0 / 0 / 0
Регистрация: 15.11.2017
Сообщений: 34
14.12.2017, 14:44  [ТС] 14
CoderHuligan, да, такая строчка не корректна, я забыла слеш перед кавычкой.
0
0 / 0 / 0
Регистрация: 10.10.2017
Сообщений: 6
16.01.2018, 11:26 15
Вот моя программа на эту тему,вроде все должно работать правильно,но в конечном файле,все выглядит будто кодировка слетела,помогите испроавить
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#define _CRT_SECURE_NO_WARNINGS
#include"stdio.h"
#include"conio.h"
#include "locale.h"
 
 
 
int main(void) 
{
    int i; char znak;
    setlocale(LC_ALL, "Rus");//sdsdsdsdsdsdsd
    FILE *jake, *output;
 
    jake = fopen("commend.txt", "r");
    output = fopen("result.txt", "w");
 
    //fopen_s(&jake,"commend.txt", "r");
    //fopen_s(&output,"result.txt", "w");
    if (jake == NULL)
        printf("ошибка\n");
    else
        printf("выполнено\n");
    while (znak = fgetc(jake) != EOF)
    {
        if (znak != '/')
        {
            if (znak != '"' && znak != '\'')
            {
                fputc(znak, output);
                znak = fgetc(jake);
            }
        }
        if (znak == '\'' || znak == '"')
        {
            if (znak == '\'')
            {
                fputc(znak, output);
                znak = fgetc(jake);
                while (znak != '\'')
                {
                    fputc(znak, output);
                    znak = fgetc(jake);
                }
 
 
            }
            if (znak == '"')
            {
                fputc(znak, output);
                znak = fgetc(jake);
                while (znak != '"')
                {
                    fputc(znak, output);
                    znak = fgetc(jake);
                }
            }
            fputc(znak, output);
            znak = fgetc(jake);
          }
          
        
          
        if (znak == '/')
        {
            znak = fgetc(jake);
            if (znak != '/' && znak != '*')
            {
                fputc('/', output);
            }
                    if (znak == '/')
                      {
                           while (znak != '\n')
                            {
                              znak = fgetc(jake);
                            }
 
                       }
            fputc(znak, output);
            znak = fgetc(jake);
            if (znak == '*')
            {   
                int c = 0;
                while (c == 0)
                {
                    znak = fgetc(jake);
                        while (znak != '*')
                         {
                        znak = fgetc(jake);
                         }
                             znak = fgetc(jake);
                                    if (znak == '/') 
                                   {
                                     znak = fgetc(jake);
                                     c++;
                                    }
                                      
                 }
             }
       }
   }
    fclose(jake);
    fclose(output);
 
    printf_s("ready");
    _getch();
 
 
}
0
280 / 215 / 98
Регистрация: 11.08.2016
Сообщений: 759
17.01.2018, 21:18 16
Цитата Сообщение от ALexAlexAlexAle
SlavaSokolov, я и хочу, чтобы внутри кавычек не удалялось.
ALexAlexAlexAle, можно создать два "флага" и условие печати сделать такое:
Если флаг1 равно коммент и флаг2 не равно Строка.

Добавлено через 20 минут
ЗЫ...
C
1
2
3
4
5
6
//Объявление флагов и инициализация
#define FALSE 0
#define TRUE 1
 
_Bool comment_state = FALSE;
_Bool string_state = FALSE;


C
1
2
3
4
5
6
//Условие выглядит так
if(comment_state && !string_state)
{
    //Действие при нахождении комментария .
    ....
}
ЗЗЫ можно и условие оставить с одной проверкой на флаг комментария , только тогда придется сброс флага комментария реализовать моментально после установки флага строки в ИСТИНУ
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
17.01.2018, 21:18

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь.

Написать прогу удаления комментариев
Здравствуйте! Задача: Написать программму, которая бы удалила закомментированные строки (//, /*...

Нужна программа, которую можно вложить в отчет с максимальным количеством комментариев
На практике изучали язык си. Нужна хорошая программа которую можно вложить в отчет с максимальным...

Обработка строк: определить отношение объема комментариев к объему всего текста программы
Помогите сделать программу по заданию: Уровнем комментированности текста будем считать отношение...

Считать файл с произвольным количеством отрицательных и положительных чисел без учета комментариев
Добрый вечер, подскажите пожалуйста, каким образом можно считать файл (с произвольным количеством...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.