Маркируйте строку и включайте разделители в C++

Hmmm... В в большой степени многопоточных приложениях я записал, у меня обычно было несколько потоков, выполняющих ту же функцию, таким образом, я не уверен, что именование распараллеливает, очень полезно в том сценарии. Однако я действительно присваивал каждому потоку целочисленный идентификатор, который был распечатан в сообщениях журнала, сгенерированных потоком для помощи в отладке.

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

20
задан Bill the Lizard 16 September 2012 в 15:41
поделиться

5 ответов

Библиотека C ++ String Toolkit Library (StrTk) предлагает следующее решение:

std::string str = "abc,123 xyz";
std::vector<std::string> token_list;
strtk::split(";., ",
             str,
             strtk::range_to_type_back_inserter(token_list),
             strtk::include_delimiters);

В результате token_list должен содержать следующие элементы:

Token0 = "abc,"
Token1 = "123 "
Token2 = "xyz"

Можно найти другие примеры Здесь

17
ответ дан 30 November 2019 в 00:55
поделиться

if the delimiters are characters and not strings, then you can use strtok.

2
ответ дан 30 November 2019 в 00:55
поделиться

Я действительно не могу следить за вашим кодом, не могли бы вы опубликовать работающую программу?

В любом случае, это простой токенизатор без проверки крайних случаев:

#include <iostream>
#include <string>
#include <vector>

using namespace std;

void tokenize(vector<string>& tokens, const string& text, const string& del)
{
    string::size_type startpos = 0,
        currentpos = text.find(del, startpos);

    do
    {
        tokens.push_back(text.substr(startpos, currentpos-startpos+del.size()));

        startpos = currentpos + del.size();
        currentpos = text.find(del, startpos);
    } while(currentpos != string::npos);

    tokens.push_back(text.substr(startpos, currentpos-startpos+del.size()));
}

Пример ввода, delimiter = $$ :

Hello$$Stack$$Over$$$Flow$$$$!

Токены:

Hello$$
Stack$$
Over$$
$Flow$$
$$
!

Примечание: я бы никогда не стал использовать созданный мной токенизатор без тестирования! используйте boost :: tokenizer !

2
ответ дан 30 November 2019 в 00:55
поделиться

Это зависит от того, хотите ли вы использовать предыдущие разделители, следующие разделители или и то, и другое, и что вы хотите сделать со строками в начале и в конце строки, которые могут не иметь разделителей до / после них.

Я предполагаю, что вам нужно каждое слово с его предшествующими и последующими разделителями, но НЕ какие-либо строки разделителей сами по себе (например, если за последней строкой стоит разделитель).

template <class iter>
void tokenize(std::string const &str, std::string const &delims, iter out) { 
    int pos = 0;
    do { 
        int beg_word = str.find_first_not_of(delims, pos);
        if (beg_word == std::string::npos) 
            break;
        int end_word = str.find_first_of(delims, beg_word);
        int beg_next_word = str.find_first_not_of(delims, end_word);
        *out++ = std::string(str, pos, beg_next_word-pos);
        pos = end_word;
    } while (pos != std::string::npos);
}

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

0
ответ дан 30 November 2019 в 00:55
поделиться

Я сейчас немного небрежно, но это то, что у меня получилось. Я не хотел использовать ускорение, так как это школьное задание, и мой инструктор хотел, чтобы я для этого использовал find_first_of.

Спасибо за помощь.

vector<string> Tokenize(const string& strInput, const string& strDelims)
{
 vector<string> vS;

 string strOne = strInput;
 string delimiters = strDelims;

 int startpos = 0;
 int pos = strOne.find_first_of(delimiters, startpos);

 while (string::npos != pos || string::npos != startpos)
 {
  if(strOne.substr(startpos, pos - startpos) != "")
   vS.push_back(strOne.substr(startpos, pos - startpos));

  // if delimiter is a new line (\n) then addt new line
  if(strOne.substr(pos, 1) == "\n")
   vS.push_back("\\n");
  // else if the delimiter is not a space
  else if (strOne.substr(pos, 1) != " ")
   vS.push_back(strOne.substr(pos, 1));

  if( string::npos == strOne.find_first_not_of(delimiters, pos) )
   startpos = strOne.find_first_not_of(delimiters, pos);
  else
   startpos = pos + 1;

        pos = strOne.find_first_of(delimiters, startpos);

 }

 return vS;
}
4
ответ дан 30 November 2019 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: