Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.86
recovery101
1 / 1 / 0
Регистрация: 10.06.2011
Сообщений: 10
14.09.2011, 15:19     Удалить комментарии из строки #1
Привет. Вообщем такая задача: Прочитать из файла строку символов. Удалить из этой строки комментарии вида "/* ... */" (вложенные комментарии тоже удалить) . Новую строку не создавать. Вывести исходную и преобразованную строки.
Т.е. например: дана строка "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".
Помогите пожалуйста исправить.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:12     Удалить комментарии из строки #21
villu, редактор не понимает вложенные комменты (так как их не понимает компилятор). Задача меняется.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 14:14     Удалить комментарии из строки #22
как-то так
Изображения
 
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:21     Удалить комментарии из строки #23
villu, если делать, как думает редактор, то после открывающей последовательности /* нужно ждать закрывающую */, а после закрывающей - снова открывающую. Никаких вложений. По-этому в ситуации с

/**/*/**/

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

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

/*/*/

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

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

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

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

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

Размер: 1.9 Кб
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 14:30     Удалить комментарии из строки #28
потому что студия не? а я написал что оно не умеет.

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

потмоу что ЛЮБОЙ редактор рассмотрит / внутри /**/ как коммент.
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 14:41     Удалить комментарии из строки #29
Цитата Сообщение от villu Посмотреть сообщение
потмоу что ЛЮБОЙ редактор рассмотрит / внутри /**/ как коммент.
ну правильно, потому что вложенных комментов не может быть. а у нас-то ситуация совсем другая
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:00     Удалить комментарии из строки #30
ну правильно, потому что вложенных комментов не может быть. а у нас-то ситуация совсем другая
ууф..ладно.

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

123456789 вывод так? однозначные вложенные комменты, все просто.
Твой код выдает 1234*inside*/asdfa ***/56789
мой 123456789
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:15     Удалить комментарии из строки #31
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;
}
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:19     Удалить комментарии из строки #32
и в хвостах тоже
char test0[] = "/123456789/";
что должно получиться?

/123456789//**/4

тоже однозначное
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:21     Удалить комментарии из строки #33
villu, 123456789, что и получается
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:23     Удалить комментарии из строки #34
а слеши на хвостах?
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
15.09.2011, 15:49     Удалить комментарии из строки #35
Цитата Сообщение от 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 ]
Отсюда видно, что все символы после // обрабатываются как обычные символы, т.е. //, /* и */ после первой пары // никакого особого смысла не имеют. Кроме того, после первого /* остальные символы (в том числе и /* и //) никаким специальным образом не обрабатываются вплоть до */.
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:57     Удалить комментарии из строки #36
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 тут просто выясняли, что в каких случаях считать открывающей, а что - закрывающей последовательностью именно в случае со вложенными комментами.
villu
202 / 202 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 16:09     Удалить комментарии из строки #37
Sorry
/*///////*/

что должно быть?
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 16:10     Удалить комментарии из строки #38
будем думать...
silent_1991
Эксперт C++
4938 / 3014 / 149
Регистрация: 11.11.2009
Сообщений: 7,024
Завершенные тесты: 1
15.09.2011, 16:17     Удалить комментарии из строки #39
Цитата Сообщение от talis Посмотреть сообщение
Мы с villu тут просто выясняли
Да, и villu ссылался на студию, "которая не умеет", и на "другие", "которые умеют". Я же пояснил, что задача ТС не соответствует тому, как принято обрабатывать комментарии в языке С++, и поэтому не следует в этом случае ссылаться на возможности той или иной IDE для этого языка.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.09.2011, 16:27     Удалить комментарии из строки
Еще ссылки по теме:

Удалить из строки комментарии вида '/* . */". Игнорировать вложенные комментарии C++
C++ Удалить комментарии из фаила
С помощью итераторов удалить комментарии из текста программы C++

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

Или воспользуйтесь поиском по форуму:
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 16:27     Удалить комментарии из строки #40
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, признайтесь - вы ветеран бетатестирования?
Yandex
Объявления
15.09.2011, 16:27     Удалить комментарии из строки
Ответ Создать тему
Опции темы

Текущее время: 01:07. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru