Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
ka6an4eg
0 / 0 / 0
Регистрация: 25.03.2015
Сообщений: 6
#1

Фильтрация текста - C++

25.03.2015, 20:22. Просмотров 552. Ответов 13
Метки нет (Все метки)

Подскажите. Есть например массив str[] Нужно из этого массива отобрать строки которые начинаются на определенные своего рода "ключи".
C++
1
2
3
4
5
6
7
static char *str[] = "From: admin\n
                                     Subject: hi\n
                                     Sender: admin\0";
char *key1 = "To:";
char *key2 = "Subject";
char *key3 = "From:";
char *key4 = "Date:";
На выходе программа должна выдать только те строки? которые имеют эти "ключи",т.е. в данном случае результат должен быть
C++
1
2
From: admin
Subject: hi
Делаю поиск через функцию strstr(str,key), которая возвращает номер вхождения в массив этого "ключа", но при попытке занести в массив out[] заносится весь массив str[], начиная с этого вхождения. Если совпадает, то надо сравнивать с позиции этого элемента весь "ключ", следовательно если ключ имеется, то внести эту строку в некий массив out[], который будет на выходе программы.
Вот кусок из функции фильтрации, как я представляю себе ее
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
if(str[i]==key1[0]) {
        fstr=strstr(str, key1);
        strcat(out,fstr);
     }
    else if(str[i]==key2[0]) {
        fstr = strstr(str, key2);
        strcat(out,fstr);
    }
    else if(str[i]==key3[0])==0) {
       fstr= strstr(str, key3);
      strcat(out,fstr);
    }
    else if(str[i]==key4[0]) {
        fstr = strstr(str, key4);
        strcat(out,fstr);
    }
Но чувствую я, что все можно сделать намного проще. Подскажите плиз.
http://www.cyberforum.ru/cpp-beginners/thread27316.html
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
25.03.2015, 20:22
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Фильтрация текста (C++):

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

Фильтрация текста в файле
Задача вот в чём: Имеется файл с тестовыми данными, некоторые данные...

Получить от пользователя строку текста и найти самое длинное слово текста
Получить от пользователя строку текста и найти самое длинное слово текста....

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

Как сделать вывод текста, результата и продолжение текста
#include <iostream> using namespace std; int main() { int win; ...

13
S_el
2133 / 1661 / 354
Регистрация: 15.12.2013
Сообщений: 6,594
25.03.2015, 20:34 #2
Цитата Сообщение от ka6an4eg Посмотреть сообщение
Но чувствую я, что все можно сделать намного проще. Подскажите плиз.
Предлагаю создать std::vector<std::string> и удалять,если метод find не найдет в качестве вхождения с начальной позиции ни один из элементов другого std::vector<std::string>.
0
ASKMAN
10 / 10 / 5
Регистрация: 07.02.2014
Сообщений: 110
25.03.2015, 20:47 #3
А что если заменить
C++
1
static char *str[]
на
C++
1
vector<string> str
и тогда уже шаманить с функцией find. Или должен быть именно указанный тип?
0
ka6an4eg
0 / 0 / 0
Регистрация: 25.03.2015
Сообщений: 6
26.03.2015, 10:23  [ТС] #4
S_el, ASKMAN, не могу так сделать, т.к. идет динамический ввод текста, т.е. не зная его длинну.
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
char* gettext() {
    static  char *str;
    static size_t size = 0;
    static int newln = 0;
    
    char ch = getchar();
    if (newln && ((ch == '\n') || (ch == EOF))) {
        str = (char*)malloc(sizeof(char) * (size + 1));
        if(!str) {
            cout<<"[error]";
            exit(1);
        }
 
        str[size] = 0;
        newln = 0;
    }
    else {
        size++;
        newln = (ch == '\n');
        gettext();
        str[--size] = ch;
    }
    
    return str;
}
Может это можно как то сделать через строки ?
0
gazlan
3139 / 1915 / 311
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
26.03.2015, 10:45 #5
Цитата Сообщение от ka6an4eg Посмотреть сообщение
строки которые начинаются
Ну, так начала строк и сравнивайте:
C++
1
2
3
4
if (!strncmp(pszMyStr,"Subject",strlen("Subject")))
{
   // Do smth !
}

Не по теме:

Подозреваю, что задача изначально неверно сформулирована. Откуда эти строки взялись?

0
ka6an4eg
0 / 0 / 0
Регистрация: 25.03.2015
Сообщений: 6
26.03.2015, 13:48  [ТС] #6
gazlan, может я не правильно понимаю работу вашего примера, но вроде так: если содержимое pzcMyStr совпадает с Subject то Do smth!
Ок, начало строки совпало, а как в итоге мне сохранить эту строку?Что бы например следующая, которая не несет важной для меня информации не сохранилась вместе с этой(Например строка Sender... мне не нужна, а нужны только From и Subject). Говоря слово строку я подразумеваю массив символов в котором есть указатели на новую строку"\n"
C++
1
char *str[] = "From: admin\nSender: admin\nSubject: hi\0";
0
gazlan
3139 / 1915 / 311
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
26.03.2015, 14:23 #7
Цитата Сообщение от ka6an4eg Посмотреть сообщение
массив символов в котором есть указатели на новую строку"\n"
Вызовите токенизатор. Готовый (strtok), либо собственный. И поделите буфер на строки.

Не по теме:

Я таки хочу узнать, откуда у вас взялся этот Big Buffer? Обычно, либо читается поток - тогда строка извлекается библиотечными функциями, либо маппируется файл - тогда нет необходимости в буфере. Возможно, копирование строки вообше не требуется? Например, достаточно только знать ее начало и размер?



Добавлено через 12 минут
Вот здесь было нечто сходное: Подсветить идентификаторы с файла - примитивный tokenizer ищет ключевое слово в строке.
0
Renji
2126 / 1485 / 453
Регистрация: 05.06.2014
Сообщений: 4,325
26.03.2015, 14:55 #8
Цитата Сообщение от ka6an4eg Посмотреть сообщение
Есть например массив str[] Нужно из этого массива отобрать строки которые начинаются на определенные своего рода "ключи".
Регулярные выражения.
C++
1
^(key1|key2):(.*?)$
искать до посинения.
0
ka6an4eg
0 / 0 / 0
Регистрация: 25.03.2015
Сообщений: 6
26.03.2015, 21:57  [ТС] #9
gazlan, вот набрасал код, но у меня выдает ошибку на 13 строке и пишет Code will never be executed
Пишу в CodeX под macOS
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 <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <cstring>
using namespace std;
 
 
int main(int argc, const char * argv[]) {
    char str[] ="From: admin\nSubject: hi\nSender: admin\0";
    char *pch=strtok(str, "\n\0");
    
    while (!str) {
        while (pch !=NULL) {
            if (!strncmp(str,"Subject",strlen("Subject")))
            {
                cout<<pch;
                pch=strtok(NULL,"\n");
            }
            
        }
 
    }
    
    return 0;
}
и правильно ли я понимаю идею, алгоритм? или все в корне не правильно?

Добавлено через 2 минуты
Renji, к сожалению ни разу не сталкивался с ними, для меня это что-то новенькое. Попытался найти пример подходящий, но не удалось. Может и не туда смотрел. Как их можно применить в моем примере?
0
gazlan
3139 / 1915 / 311
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
26.03.2015, 22:34 #10
Цитата Сообщение от ka6an4eg Посмотреть сообщение
macOS

Не по теме:

Сто лет не видел :-)


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
#include <stdio.h>
#include <string.h>
 
static bool IsContainTag(const char* const pszLine)
{
   if (!pszLine || !*pszLine)
   {
      return false;
   }
   
   if (!strncmp(pszLine,"From: ",strlen("From: ")))
   {
      return true;
   }
   
   if (!strncmp(pszLine,"Subject: ",strlen("Subject: ")))
   {
      return true;
   }
   
   if (!strncmp(pszLine,"Sender: ",strlen("Sender: ")))
   {
      return true;
   }
   
   return false;
}
 
static char    pszText[] = "From: Baby, now you're speaking my language\nSubject: Just tell me you're down\nAnd you don't really gotta explain it\nJust tell me right now\nSender: Boy, you make my heart go\nYou make my heart go\nYou make my heart go\n";
 
int main(int argc,char** argv)
{
   char*    pszLine = strtok(pszText,"\n");
   
   if (IsContainTag(pszLine)) 
   {
      printf("%s\n",pszLine);
   }
   
   do 
   {
      pszLine = strtok(NULL,"\n");
      
      if (IsContainTag(pszLine)) 
      {
         printf("%s\n",pszLine);
      }
   } 
   while (pszLine);
   
   return 0;
}
0
Миниатюры
Фильтрация текста  
ka6an4eg
0 / 0 / 0
Регистрация: 25.03.2015
Сообщений: 6
26.03.2015, 22:54  [ТС] #11
gazlan, спасибо большое! А я почему то даже и не думал в сторону bool
А подскажите, пожалуйста, то что я написал бред бредом ?
0
Renji
2126 / 1485 / 453
Регистрация: 05.06.2014
Сообщений: 4,325
26.03.2015, 23:01 #12
Цитата Сообщение от ka6an4eg Посмотреть сообщение
Renji, к сожалению ни разу не сталкивался с ними, для меня это что-то новенькое. Попытался найти пример подходящий, но не удалось. Может и не туда смотрел. Как их можно применить в моем примере?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include<string>
#include<iostream>
#include<boost/regex.hpp>
using namespace std;
 
int main()
{
    string str="From: admin\nSubject: hi\nSender: admin";
    boost::regex exp("^(From|Subject):(.*?)$");
    boost::smatch match;
    string::const_iterator end=str.end();
    for(string::const_iterator pos=str.begin();
        boost::regex_search(pos,end,match,exp);
        pos=match[0].second)
        cout<<match[0]<<endl;
    return 0;
}
0
gazlan
3139 / 1915 / 311
Регистрация: 27.08.2010
Сообщений: 5,132
Записей в блоге: 1
26.03.2015, 23:13 #13
Цитата Сообщение от ka6an4eg Посмотреть сообщение
то что я написал
Вы так и не рассказали про исходную задачу. Возможно, ее надо решать иным образом.

Не по теме:

Всё следует упрощать до тех пор, пока это возможно, но не более того. (©) Альберт Эйнштейн

0
ka6an4eg
0 / 0 / 0
Регистрация: 25.03.2015
Сообщений: 6
27.03.2015, 08:07  [ТС] #14
Renji, Спасибо, сейчас буду сидеть разбираться.

Добавлено через 4 минуты
gazlan, Составить программу построчной фильтрации текста. Суть фильтра — отбор строк, начинающихся с одного из следующих выражений: «Date:», «From:»,«To:», «Subject:». Текстовые строки подаются на стандартный ввод программы, результат программы должен подаваться на стандартный вывод. Процедура фильтрации должна быть оформлена в виде отдельной функции, которой подается на вход массив строк, выделенных в динамической памяти и его длина. На выходе функция возвращает указатель на NULL-терминированный массив с найденными строками (последним элементом массива добавлен NULL для обозначения, что данных больше нет).
Получается что ваш способ не подходит, хотя мне очень понравился.

Добавлено через 7 часов 6 минут
Renji, мне этот способ неподходит, т.к. библиотеки boost не блыо в версии с99. А компиляцию мне надо запускать именно с этим ключем. Спасибо что поделились своей точкой зрения на этот вопрос
0
27.03.2015, 08:07
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.03.2015, 08:07
Привет! Вот еще темы с решениями:

Заданы два текста. Определить, можно ли получить первый текст перестановкой слов второго текста.
Заданы два текста. Определить, можно ли получить первый текст перестановкой...

Фильтрация изображений
Привет ребята. Какие есть алгоритмы по фильтрации изображений(подавление...

Форматирование текста и изменение цвета текста в консоли
Подскажите пожалуйста, как форматировать текст в консоли, а также как менять...

Выводит адрес текста, вместо самого текста
#include &lt;iostream&gt; #include &lt;fstream&gt; #include &lt;cstring&gt; #include &lt;conio.h&gt;...


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

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

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