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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 36, средняя оценка - 4.86
recovery101
1 / 1 / 0
Регистрация: 10.06.2011
Сообщений: 10
#1

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

14.09.2011, 15:19. Просмотров 4660. Ответов 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
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
14.09.2011, 15:19
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Удалить комментарии из строки (C++):

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

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

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

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

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

Прочитать программу на языке C++ и удалить все комментарии - C++
кто-нибудь)помогите написать эту программу=\

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
talis
791 / 543 / 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;
}
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:19 #32
и в хвостах тоже
char test0[] = "/123456789/";
что должно получиться?

/123456789//**/4

тоже однозначное
0
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 15:21 #33
villu, 123456789, что и получается
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 15:23 #34
а слеши на хвостах?
0
silent_1991
Эксперт С++
4964 / 3040 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 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 ]
Отсюда видно, что все символы после // обрабатываются как обычные символы, т.е. //, /* и */ после первой пары // никакого особого смысла не имеют. Кроме того, после первого /* остальные символы (в том числе и /* и //) никаким специальным образом не обрабатываются вплоть до */.
0
talis
791 / 543 / 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 тут просто выясняли, что в каких случаях считать открывающей, а что - закрывающей последовательностью именно в случае со вложенными комментами.
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 16:09 #37
Sorry
/*///////*/

что должно быть?
0
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 16:10 #38
будем думать...
0
silent_1991
Эксперт С++
4964 / 3040 / 149
Регистрация: 11.11.2009
Сообщений: 7,027
Завершенные тесты: 1
15.09.2011, 16:17 #39
Цитата Сообщение от talis Посмотреть сообщение
Мы с villu тут просто выясняли
Да, и villu ссылался на студию, "которая не умеет", и на "другие", "которые умеют". Я же пояснил, что задача ТС не соответствует тому, как принято обрабатывать комментарии в языке С++, и поэтому не следует в этом случае ссылаться на возможности той или иной IDE для этого языка.
0
talis
791 / 543 / 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, признайтесь - вы ветеран бетатестирования?
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 17:20 #41
не. просто отпуск через неделю.
Но в Suunto с этого начинал, ты прав

кстати когда проходил там собеседование на программера задание было в написании парсера следующего (до сих пор храню)

(К сожалению оригинал задания не сохранился, да и толку от него нет -- он на финском.)

C++
1
2
3
4
"\n[[+-{$(width)}]{$(rows)}+"
"[\\n|[$(space){$(width)}|]"
"{$(rows)}]{$(height)}\\n]"
"{$(lines)}[+-{$(width)}]{$(rows)}+\\n"
Это строка
в строке:
[] - цикл
{число} количество повторений цикла []{10}, либо единичного сивола !{10}
пример: 1{5} = 11111
[12]{5} = 1212121212
[!] = !
[!]{0} = пусто
\x0000 - символ по хекс коду (\x0F0)
\x - экранированный символ (n, t, \, итд по списку + [] {} $)
$(переменная) переменная, получаемая ран-тайм. переменные могут передаваться в [] и {}
например count = 10
sym = !
[$(sym)]{$(count)} = !!!!!!!!!!
парсер должен из всего этого безобразия собрать строку
(результат в аттаче) принимая, что
"height" = 2;
"width" = 13;
"rows" = 10;
"lines" = 5;
"space" = пробел или что другое

Но! запрещены регулярные выражения, запрещен С++, запрещены функции типа strXXX. Только голый С, функции памяти (выделить/освободить) (статические буферы так же допускаются), указатели. На решение неделя.

Если вдруг интересно -- хорошая разминка. Почему-то я думаю, что ты сможешь
1
Миниатюры
Удалить комментарии из строки  
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 17:33 #42
villu, спасибо, задание действительно интересное. Складывается ощущение, что компания специализируется на придумывании каверзных заданий.

Вопрос:

Цитата Сообщение от villu Посмотреть сообщение
[+-{$(width)}]
Как понимать последовательность +-? Конкатенация с отрицательным значением width?

Добавлено через 1 минуту
Синтаксис - убейся... Немецкая шифровка. Ну, или финская...
0
villu
203 / 204 / 4
Регистрация: 06.08.2011
Сообщений: 600
Записей в блоге: 1
15.09.2011, 17:35 #43
нет. + и - это простые символы. то есть при width = 13 должно быть
[+-------------]

Добавлено через 1 минуту
надо в другую тему идти, пока модератор не убил
0
talis
791 / 543 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
15.09.2011, 17:37 #44
Цитата Сообщение от villu Посмотреть сообщение
надо в другую тему идти, пока модератор не убил
Жду другую тему или личку.
0
KING1994
-68 / 6 / 0
Регистрация: 18.07.2011
Сообщений: 77
15.09.2011, 18:06 #45
НЕпонимаю зачем так сложно писать... вот мой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include<conio.h>
#include<iostream>
#include<string>
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    FILE * f;
    string a,s1,s2;int i,j;char b[100];
    s1="/*";s2="*/";
    f = fopen ("C:\\okfile.txt", "r");
    fgets(b,100,f);
        a=b;
        i=a.find(s1);j=a.find(s2);
        a.erase(i,j-i+2);
        cout<<a<<endl;
        getch();
    return 0;
}
Добавлено через 18 минут
Пардон тот код удалял только 1-н коментарий.Вот код который удаляет любое количество коментариев:
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
#include "stdafx.h"
#include<conio.h>
#include<iostream>
#include<string> 
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    FILE * f;
    string a,s1,s2;int i,j;char b[100];
    s1="/*";s2="*/";
    f = fopen ("C:\\okfile.txt", "r");
    fgets(b,100,f); 
        a=b;
        do
        { 
        i=a.find(s1); 
        if(i==-1)break;
        j=a.find(s2);
        if(j==-1)break;
        a.erase(i,j-i+2);
        }while(j!=-1);
        cout<<a<<endl;
        getch();
    return 0;
}
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
15.09.2011, 18:06
Привет! Вот еще темы с ответами:

Удалить комментарии из файла. Помогите найти ошибку. - C++
программа должна распознать комменитарии вида /* */ и // из входного файла, и записать в выходной файл программу без комментариев... 1...

С помощью итераторов удалить комментарии из текста программы - C++
Здравствуйте помогите пожалуйста решить задачу Напишите программу, которая выбрасывает комментарии из C++ программы. То есть, читает из...

Комментарии к программе на строки - C++
#include &lt;iostream&gt; #include &lt;sstream&gt; #include &lt;string&gt; using namespace std; int main() { string...

Заменить комментарии нечетной строки комментариями четной - C++
Исходный текст должен содержаться в одном файле, результат — во втором файле. В программе на ассемблере заменить комментарии нечетной...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
15.09.2011, 18:06
Ответ Создать тему
Опции темы

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