Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.75/63: Рейтинг темы: голосов - 63, средняя оценка - 4.75
1 / 1 / 0
Регистрация: 10.06.2011
Сообщений: 10

Удалить комментарии из строки

14.09.2011, 15:19. Показов 13212. Ответов 48
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет. Вообщем такая задача: Прочитать из файла строку символов. Удалить из этой строки комментарии вида "/* ... */" (вложенные комментарии тоже удалить) . Новую строку не создавать. Вывести исходную и преобразованную строки.
Т.е. например: дана строка "gfsgsdsf /* jhasd */ asdas" и на выходе он выдает "gfsgsdsf asdas". Вот мой код
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
#include "stdafx.h"
#include <conio.h>
#include <stdio.h>
#include <iostream>
using namespace std;
void main ()
{
   setlocale (0,"Rus");
   int m = 0, n = 0;
   FILE * f;
   char buf[100];
   int length;
   f = fopen ("C:\\okfile.txt", "r");
   if (f == NULL) 
       perror ("Ошибка");
   else 
   {
     fgets (buf, 100 , f);
     puts (buf);
     fclose (f);
   }
   length = strlen(buf);
   for(int i = 0; i < length ; i++)
   {
       if ((buf[i] == '/') && (buf[i + 1] == '*'))
       {
          m = i;
       }
       if ((buf[i - 1] == '*') && (buf[i] == '/'))   
       {
          n = i;   
       }
       if ((m != 0) && (i == n))
       {
       int len = strlen(buf)-m;
       memmove(buf+m-1, buf+n+1, len);
       }
   }
   puts (buf);
   getch();
}
Но он не удаляет вложенные комментарии (комментарии в комментарии), т.е. надо чтобы при вводе строки "asdasd /* asd /*123*/ dsa*/ asdasd" выводил "asdasd asdasd".
Помогите пожалуйста исправить.
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.09.2011, 15:19
Ответы с готовыми решениями:

Удалить из строки комментарии вида '/* ... */". Игнорировать вложенные комментарии.
#include &lt;iostream&gt; #include &lt;stdio.h&gt; #include &lt;string.h&gt; using namespace std; int main(int argc, char *argv) { ...

Удалить из строки комментарии вида '/* . */". Игнорировать вложенные комментарии
Всем привет! есть строка вида : char str=&quot;abc/*111/*def/*222*/ghi*/333*/jkl&quot;; нужно получить abc /*def ghi*/ jkl Реально ли так...

Удалить из строки слова, которые встречаются заданное число раз (нужны комментарии)
Помогите пояснить программу пожалуйста? Написать комментарии к каждой строке?) #include &lt;iostream&gt; #include &lt;string&gt; ...

48
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:12
Студворк — интернет-сервис помощи студентам
villu, редактор не понимает вложенные комменты (так как их не понимает компилятор). Задача меняется.
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 14:14
как-то так
Изображения
 
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:21
villu, если делать, как думает редактор, то после открывающей последовательности /* нужно ждать закрывающую */, а после закрывающей - снова открывающую. Никаких вложений. По-этому в ситуации с

/**/*/**/

первые два символа - открывают, вторые два - закрывают, а третьи два не рассматриваются как закрывающий коммент, потому что после закрытия ожидается открытие. Если же добавить возможность вложенных комментов - ситуация сильно меняется. После одного закрывающего может стоять другой закрывающий.

Добавлено через 1 минуту
так же вот ещё пример:

/*/*/

в любом редакторе вторые два символа не рассматриваются как вторая открывающая последовательность. вместо этого, последние два символа рассматриваются как закрывающая. с вложениями всё иначе - после одного открывающего может стоять другой
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 14:22
1: редактор открой.
2: например студия действительно не понимает комменты вложенные, а некоторые понимают.
а третьи два не рассматриваются как закрывающий коммент, потому что после закрытия ожидается открытие.
Вы говорите глупости (с)
ЛЮБОЙ редактор с такой чепухой справляется. Выше уже кинул картинку. Вот еще одна.
Изображения
 
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 14:24
Цитата Сообщение от talis Посмотреть сообщение
[b]
/*/*/
и опять ой!. потмоу что ЛЮБОЙ редактор рассмотрит / внутри /**/ как коммент.

еще картинку прислать?
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:26
Цитата Сообщение от villu Посмотреть сообщение
Вы говорите глупости (с)
ЛЮБОЙ редактор с такой чепухой справляется
Не любой:



Code::Blocks 10.05. Ниже видно, что gcc ругается.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:28
Цитата Сообщение от villu Посмотреть сообщение
и опять ой!. потмоу что ЛЮБОЙ редактор рассмотрит / внутри /**/ как коммент.
и опять ой:

Название: 1.JPG
Просмотров: 35

Размер: 1.9 Кб
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 14:30
потому что студия не? а я написал что оно не умеет.

Добавлено через 51 секунду
а там ровно такая ситуация, как я и описал.

потмоу что ЛЮБОЙ редактор рассмотрит / внутри /**/ как коммент.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:41
Цитата Сообщение от villu Посмотреть сообщение
потмоу что ЛЮБОЙ редактор рассмотрит / внутри /**/ как коммент.
ну правильно, потому что вложенных комментов не может быть. а у нас-то ситуация совсем другая
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:00
ну правильно, потому что вложенных комментов не может быть. а у нас-то ситуация совсем другая
ууф..ладно.

вот еще одна проверка
1234/**sdfa /*inside*/asdfa **/56789

123456789 вывод так? однозначные вложенные комменты, все просто.
Твой код выдает 1234*inside*/asdfa ***/56789
мой 123456789
1
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:15
villu, да, действительно. Я забыл обновить предыдущий символ, если текст находится внутри комментария:

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
string nocomment( char * str )
{
    int level = 0;
    string out;
 
    char prev = 0,
         buff[2] = {0, 0};
 
    for( char *p = str; *p; p++ )
    {
        //cout << '\n' << *p << ": ";
 
        if( *p == '/' )
        {
            if( prev == '*' ) // закрываюший коммент
            {
                prev = 0;
 
                if( !level )
                {
                   //prev = 0;
                   //cout << "closing comment outside of comment area ";
                   out += "/";
                   continue;
                }
 
                level--;
 
                //cout << "closing comment:" << prev << " level is now " << level << ' ';
                //prev = 0;
 
                continue;
            }
 
            prev = *p;
            continue;
        }
        else if( *p == '*' )
        {
            if( prev == '/' ) // открываюший коммент
            {
                level++;
 
                //cout << "opening comment. level is now " << level << ' ';
 
                prev = 0;
                continue;
            }
 
            //prev = *p;
        }
 
        if( !level )
        {
            //prev = *p;
            buff[0] = *p;
            out += buff;
        }
 
        prev = *p;
    }
 
    return out;
}
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:19
и в хвостах тоже
char test0[] = "/123456789/";
что должно получиться?

/123456789//**/4

тоже однозначное
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:21
villu, 123456789, что и получается
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:23
а слеши на хвостах?
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
15.09.2011, 15:49
Цитата Сообщение от villu Посмотреть сообщение
например студия действительно не понимает комменты вложенные, а некоторые понимают.
Значит "некоторые" действуют не по стандарту. Студия-не студия, а исходный код парсит компилятор, он же выкидывает комментарии. И выкидывает он их по определённым правилам, описанным в стандарте. Нас интересует 2.8 - Comments, а именно примечание:
[ Note: The comment characters //, /*, and */ have no special meaning within a // comment and are treated just like other characters. Similarly, the comment characters // and /* have no special meaning within a /* comment. —end note ]
Отсюда видно, что все символы после // обрабатываются как обычные символы, т.е. //, /* и */ после первой пары // никакого особого смысла не имеют. Кроме того, после первого /* остальные символы (в том числе и /* и //) никаким специальным образом не обрабатываются вплоть до */.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:57
villu, вот, со слешами на хвостах и с правильной обработкой /**/*/**/. К тому же с гораздо более элегантным кодом:

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
string nocomment( char * str )
{
    unsigned int level = 0;
    string out;
 
    for( char *p = str; *p; p++ )
    {
        if( p != str && *(p - 1) == '*' && *p == '/' && level ) // закрывающий коммент ненулевого уровня
        {
            level--;
            continue;
        }
        else if( *p == '/' && *(p + 1) == '*' ) // открывающий коммент
            level++;
 
        if( !level )
            out.push_back( *p );
    }
 
    return out;
}
 
int main()
{
    cout << "output:\n" << nocomment( "*///*bad*/Hello, /*world*/sailor! How /* is /* your /* comment */ */ doing?**/do/* */ you/***/ do?" )
         << '\n' << nocomment( "***/" ) <<
         '\n' << nocomment( "132/**/*/**/456789" ) <<
         '\n' << nocomment( "1234/**sdfa /*inside*/asdfa **/56789" ) <<
         '\n' << nocomment( "/123456789//**/4" );
 
    return 0;
}
Я вас, наверное, замучал уже. Голова, просто, не варит уже который день, и её хочется расшевелить. Спасибо за примеры!

Добавлено через 1 минуту
Цитата Сообщение от silent_1991 Посмотреть сообщение
Кроме того, после первого /* остальные символы (в том числе и /* и //) никаким специальным образом не обрабатываются вплоть до */.
Да, то есть вложения не учитываются. А у ТС задача совсем другая - со вложениями. Мы с villu тут просто выясняли, что в каких случаях считать открывающей, а что - закрывающей последовательностью именно в случае со вложенными комментами.
0
204 / 205 / 16
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 16:09
Sorry
/*///////*/

что должно быть?
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 16:10
будем думать...
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
15.09.2011, 16:17
Цитата Сообщение от talis Посмотреть сообщение
Мы с villu тут просто выясняли
Да, и villu ссылался на студию, "которая не умеет", и на "другие", "которые умеют". Я же пояснил, что задача ТС не соответствует тому, как принято обрабатывать комментарии в языке С++, и поэтому не следует в этом случае ссылаться на возможности той или иной IDE для этого языка.
0
 Аватар для talis
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 16:27
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
string nocomment( char * str )
{
    unsigned int level = 0;
    string out;
 
    enum
    {
        s_none,
        s_open,
        s_close
    }
    last_seq = s_none;
 
    for( char *p = str; *p; p++ )
    {
        if( p != str && *(p - 1) == '*' && *p == '/' && level && last_seq != s_open ) // закрывающий коммент ненулевого уровня
        {
            last_seq = s_close;
            level--;
            continue;
        }
        else if( *p == '/' && *(p + 1) == '*' ) // открывающий коммент
        {
            level++;
            last_seq = s_open;
            p++; // мы заведомо знаем, что следующий символ не нужно учитывать
        }
        else
            last_seq = s_none;
 
        if( !level )
            out.push_back( *p );
    }
 
    return out;
}
Добавлено через 9 минут
villu, признайтесь - вы ветеран бетатестирования?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
15.09.2011, 16:27
Помогаю со студенческими работами здесь

Удалить комментарии из фаила
Здравствуйте. Есть вот такие фаилы: # 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware # File Created: 07.12.2014...

Удалить комментарии из файлов С и С++
Создать функцию удаляющую комментарии из файлов С и С++. Функция принимает в качестве параметра имя входного и выходного файлов и удаляет...

Удалить комментарии из файла
Здравствуйте, написал программу, которая удаляет комментарии в файле #include &lt;iostream&gt; #include &lt;fstream&gt; void...

Из строки удалить среднюю букву, если длина строки нечетная, иначе - удалить две средние буквы
Из строки удалить среднюю букву, если длина строки нечетная, иначе - удалить две средние буквы.

Из строки удалить среднею букву, если длина строки нечетная, иначе удалить две средних буквы
из ряда удалить среднею букву ,если длина ряда не парная ,тогда удалить две средних буквы


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Программный отбор значения справочника
Maks 21.03.2026
Процедура ВодителиНачалоВыбора(Элемент, ДанныеВыбора, ВыборДобавлением, СтандартнаяОбработка) / / Отключаем стандартную обработку (стандартное открытие формы выбора без фильтров) . . .
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru