Вы можете проверить срок службы, используя
bool isProcessRunning(HANDLE process)
{
return WaitForSingleObject( process, 0 ) == WAIT_TIMEOUT;
}
Ваш простой случай может быть легко построен с использованием метода std::string::find
. Тем не менее, взгляните на Boost.Tokenizer . Это великолепно. В Boost обычно есть очень крутые струнные инструменты.
Нет никакого прямого способа сделать это. Пошлите этот исходный код проекта кода узнать, как создать класс для этого.
Я думал, для именно это >>
был оператор на строковых потоках:
string word; sin >> word;
Для простого материала я просто использую следующее:
unsigned TokenizeString(const std::string& i_source,
const std::string& i_seperators,
bool i_discard_empty_tokens,
std::vector<std::string>& o_tokens)
{
unsigned prev_pos = 0;
unsigned pos = 0;
unsigned number_of_tokens = 0;
o_tokens.clear();
pos = i_source.find_first_of(i_seperators, pos);
while (pos != std::string::npos)
{
std::string token = i_source.substr(prev_pos, pos - prev_pos);
if (!i_discard_empty_tokens || token != "")
{
o_tokens.push_back(i_source.substr(prev_pos, pos - prev_pos));
number_of_tokens++;
}
pos++;
prev_pos = pos;
pos = i_source.find_first_of(i_seperators, pos);
}
if (prev_pos < i_source.length())
{
o_tokens.push_back(i_source.substr(prev_pos));
number_of_tokens++;
}
return number_of_tokens;
}
Трусливая правовая оговорка: Я пишу программное обеспечение обработки данных реального времени, где данные входят через двоичные файлы, сокеты или некоторый вызов API (Платы ввода-вывода, камера). Я никогда не использую эту функцию для чего-то более сложного или строго ограниченного во времени, чем чтение внешних конфигурационных файлов на запуске.
Если Вы готовы использовать C, можно использовать функция strtok. Необходимо обратить внимание на проблемы многопоточности при использовании его.
Не обижайтесь, ребята, но для такой простой задачи вы делаете вещи более сложными . Есть много причин использовать Boost . Но для чего-то такого простого это все равно, что ударить муху санями 20 #.
void
split( vector<string> & theStringVector, /* Altered/returned value */
const string & theString,
const string & theDelimiter)
{
UASSERT( theDelimiter.size(), >, 0); // My own ASSERT macro.
size_t start = 0, end = 0;
while ( end != string::npos)
{
end = theString.find( theDelimiter, start);
// If at end, use length=maxLength. Else use length=end-start.
theStringVector.push_back( theString.substr( start,
(end == string::npos) ? string::npos : end - start));
// If at end, use start=maxSize. Else use start=end+delimiter.
start = ( ( end > (string::npos - theDelimiter.size()) )
? string::npos : end + theDelimiter.size());
}
}
Например (для случая Дуга),
#define SHOW(I,X) cout << "[" << (I) << "]\t " # X " = \"" << (X) << "\"" << endl
int
main()
{
vector<string> v;
split( v, "A:PEP:909:Inventory Item", ":" );
for (unsigned int i = 0; i < v.size(); i++)
SHOW( i, v[i] );
}
И да, мы могли бы использовать split (), чтобы вернуть новый вектор вместо передачи одного. Это тривиально, чтобы обернуть и перегрузить. Но в зависимости от того, что я делаю, я часто нахожу лучше повторно использовать уже существующие объекты, чем всегда создавать новые. (Пока я не забуду опустошить вектор между ними!)
Ссылка: http://www.cplusplus.com/reference/string/string/ .
(Первоначально я писал ответ на вопрос Дуга: Изменение и извлечение строк C ++ на основе разделителей (закрыто) . Но поскольку Мартин Йорк закрыл этот вопрос с помощью указателя здесь ... просто обобщите мой код.)
pystring - это небольшая библиотека, которая реализует набор строковых функций Python, включая метод split:
#include <string>
#include <vector>
#include "pystring.h"
std::vector<std::string> chunks;
pystring::split("this string", chunks);
// also can specify a separator
pystring::split("this-string", chunks, "-");
Вот пример класса токенизатора, который может делать то, что вы хотите
//Header file
class Tokenizer
{
public:
static const std::string DELIMITERS;
Tokenizer(const std::string& str);
Tokenizer(const std::string& str, const std::string& delimiters);
bool NextToken();
bool NextToken(const std::string& delimiters);
const std::string GetToken() const;
void Reset();
protected:
size_t m_offset;
const std::string m_string;
std::string m_token;
std::string m_delimiters;
};
//CPP file
const std::string Tokenizer::DELIMITERS(" \t\n\r");
Tokenizer::Tokenizer(const std::string& s) :
m_string(s),
m_offset(0),
m_delimiters(DELIMITERS) {}
Tokenizer::Tokenizer(const std::string& s, const std::string& delimiters) :
m_string(s),
m_offset(0),
m_delimiters(delimiters) {}
bool Tokenizer::NextToken()
{
return NextToken(m_delimiters);
}
bool Tokenizer::NextToken(const std::string& delimiters)
{
size_t i = m_string.find_first_not_of(delimiters, m_offset);
if (std::string::npos == i)
{
m_offset = m_string.length();
return false;
}
size_t j = m_string.find_first_of(delimiters, i);
if (std::string::npos == j)
{
m_token = m_string.substr(i);
m_offset = m_string.length();
return true;
}
m_token = m_string.substr(i, j - i);
m_offset = j;
return true;
}
Пример:
std::vector <std::string> v;
Tokenizer s("split this string", " ");
while (s.NextToken())
{
v.push_back(s.GetToken());
}
Ускорение имеет функцию сильного разделения: boost ::gorith :: split .
Пример программы:
#include <vector>
#include <boost/algorithm/string.hpp>
int main() {
auto s = "a,b, c ,,e,f,";
std::vector<std::string> fields;
boost::split(fields, s, boost::is_any_of(","));
for (const auto& field : fields)
std::cout << "\"" << field << "\"\n";
return 0;
}
Вывод:
"a"
"b"
" c "
""
"e"
"f"
""
Еще один быстрый способ - использовать getline
. Примерно так:
stringstream ss("bla bla");
string s;
while (getline(ss, s, ' ')) {
cout << s << endl;
}
Если хотите, вы можете создать простой метод split()
, возвращающий vector<string>
, что действительно полезно.
Вы можете использовать потоки, итераторы и алгоритм копирования, чтобы сделать это довольно напрямую.
#include <string>
#include <vector>
#include <iostream>
#include <istream>
#include <ostream>
#include <iterator>
#include <sstream>
#include <algorithm>
int main()
{
std::string str = "The quick brown fox";
// construct a stream from the string
std::stringstream strstr(str);
// use stream iterators to copy the stream to the vector as whitespace separated strings
std::istream_iterator<std::string> it(strstr);
std::istream_iterator<std::string> end;
std::vector<std::string> results(it, end);
// send the vector to stdout.
std::ostream_iterator<std::string> oit(std::cout);
std::copy(results.begin(), results.end(), oit);
}
токенизатор Повышения класс может сделать этот вид вещи довольно простым:
#include <iostream>
#include <string>
#include <boost/foreach.hpp>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int, char**)
{
string text = "token, test string";
char_separator<char> sep(", ");
tokenizer< char_separator<char> > tokens(text, sep);
BOOST_FOREACH (const string& t, tokens) {
cout << t << "." << endl;
}
}
Обновленный для C++ 11:
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int, char**)
{
string text = "token, test string";
char_separator<char> sep(", ");
tokenizer<char_separator<char>> tokens(text, sep);
for (const auto& t : tokens) {
cout << t << "." << endl;
}
}
Используйте strtok. По-моему, нет потребности создать класс вокруг маркирования, если strtok не предоставляет Вам тем, в чем Вы нуждаетесь. Это не могло бы, но в 15 + годы записи различного кода парсинга в C и C++, я всегда использовал strtok. Вот пример
char myString[] = "The quick brown fox";
char *p = strtok(myString, " ");
while (p) {
printf ("Token: %s\n", p);
p = strtok(NULL, " ");
}
Несколько протестов (который не мог бы удовлетворить Вашим потребностям). Строка "уничтожается" в процессе, означая, что символы ЭОС помещаются встроенные в местах delimter. Корректное использование могло бы потребовать, чтобы Вы сделали версию неконстанты строки. Можно также изменить список разделителей середина синтаксического анализа.
По моему собственному мнению, вышеупомянутый код намного более прост и легок для использования, чем запись отдельного класса для него. Мне это - одна из тех функций, которые обеспечивает язык, и это делает это хорошо и чисто. Это просто "C базирующееся" решение. Это является соответствующим, это легко, и Вы не должны писать много дополнительного кода:-)
Вот реальный простой:
#include <vector>
#include <string>
using namespace std;
vector<string> split(const char *str, char c = ' ')
{
vector<string> result;
do
{
const char *begin = str;
while(*str != c && *str)
str++;
result.push_back(string(begin, str));
} while (0 != *str++);
return result;
}
MFC/ATL имеет очень хороший токенизатор. Из MSDN:
CAtlString str( "%First Second#Third" );
CAtlString resToken;
int curPos= 0;
resToken= str.Tokenize("% #",curPos);
while (resToken != "")
{
printf("Resulting token: %s\n", resToken);
resToken= str.Tokenize("% #",curPos);
};
Output
Resulting Token: First
Resulting Token: Second
Resulting Token: Third
Я знаю, что вы просили решение на C ++, но вы можете счесть это полезным:
Qt
#include <QString>
...
QString str = "The quick brown fox";
QStringList results = str.split(" ");
Преимущество над Boost в этом примере состоит в том, что это прямое отображение один в один на код вашего сообщения.
Подробнее см. Документация Qt