문자열 단어를 반복하려면 어떻게 해야 하나요?
공백으로 구분된 문자열의 단어를 반복하려면 어떻게 해야 합니까?
참고로 저는 C 문자열 함수나 그런 종류의 문자 조작/액세스에는 관심이 없습니다.나는 효율성보다 우아함을 선호한다.현재 솔루션:
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
int main() {
string s = "Somewhere down the road";
istringstream iss(s);
do {
string subs;
iss >> subs;
cout << "Substring: " << subs << endl;
} while (iss);
}
딜리미터로 문자열을 분할할 때 사용합니다.첫 번째는 사전 구성된 벡터에 결과를 넣고, 두 번째는 새로운 벡터를 반환합니다.
#include <string>
#include <sstream>
#include <vector>
#include <iterator>
template <typename Out>
void split(const std::string &s, char delim, Out result) {
std::istringstream iss(s);
std::string item;
while (std::getline(iss, item, delim)) {
*result++ = item;
}
}
std::vector<std::string> split(const std::string &s, char delim) {
std::vector<std::string> elems;
split(s, delim, std::back_inserter(elems));
return elems;
}
이 솔루션에서는 빈 토큰을 건너뛰지 않으므로 다음 항목에서 4개를 찾을 수 있으며, 그 중 하나는 비어 있습니다.
std::vector<std::string> x = split("one:two::three", ':');
중요한 것은 표준 라이브러리 시설에만 의존하여 입력 문자열에서 토큰을 추출하는 또 다른 방법입니다.이것은 STL 설계의 이면에 있는 힘과 우아함을 보여주는 예입니다.
#include <iostream>
#include <string>
#include <sstream>
#include <algorithm>
#include <iterator>
int main() {
using namespace std;
string sentence = "And I feel fine...";
istringstream iss(sentence);
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
ostream_iterator<string>(cout, "\n"));
}
추출된 토큰을 출력 스트림에 복사하는 대신 동일한 범용 알고리즘을 사용하여 컨테이너에 삽입할 수 있습니다.
vector<string> tokens;
copy(istream_iterator<string>(iss),
istream_iterator<string>(),
back_inserter(tokens));
을하거나...을 작성하거나vector
★★★★
vector<string> tokens{istream_iterator<string>{iss},
istream_iterator<string>{}};
Boost를 사용할 수 있는 솔루션은 다음과 같습니다.
#include <boost/algorithm/string.hpp>
std::vector<std::string> strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));
이 더 수 .stringstream
또, 은 범용 에, 모든 딜리미터를 등 )을 할 수 있습니다.
상세한 것에 대하여는, 메뉴얼을 참조해 주세요.
#include <vector>
#include <string>
#include <sstream>
int main()
{
std::string str("Split me by whitespaces");
std::string buf; // Have a buffer string
std::stringstream ss(str); // Insert the string into a stream
std::vector<std::string> tokens; // Create vector to hold our words
while (ss >> buf)
tokens.push_back(buf);
return 0;
}
템플릿 기능을 사용한 효율적이고 작고 우아한 솔루션:
template <class ContainerT>
void split(const std::string& str, ContainerT& tokens,
const std::string& delimiters = " ", bool trimEmpty = false)
{
std::string::size_type pos, lastPos = 0, length = str.length();
using value_type = typename ContainerT::value_type;
using size_type = typename ContainerT::size_type;
while (lastPos < length + 1)
{
pos = str.find_first_of(delimiters, lastPos);
if (pos == std::string::npos)
pos = length;
if (pos != lastPos || !trimEmpty)
tokens.emplace_back(value_type(str.data() + lastPos,
(size_type)pos - lastPos));
lastPos = pos + 1;
}
}
는 보통 는는보 i i를 사용한다.std::vector<std::string>
parameter유형)ContainerT
)...하지만list<...>
vector<>
직접 액세스가 필요하지 않은 경우에 사용합니다.
C이므로 C++-17을 사용할 수 .std::vector<std::string_view>
훨씬 빠르고 메모리 효율적입니다.
새로운 move semantics에서는 return 파라미터를 사용할 수 있지만 템플릿 함수에 문제가 있습니다.고정 반환 유형이 있고 템플릿이 필요하지 않은 경우 해당 유형으로 변경할 수 있습니다(단, 동일한 컨테이너를 사용하여 점진적으로 호출할 수 없게 됩니다.
마지막으로 마지막 선택적 매개 변수를 통해 결과에서 빈 토큰을 잘라낼지 여부를 지정할 수 있습니다.
필요한 건std::string
통해 <string>
스트림이나 부스트 라이브러리는 사용하지 않지만 이러한 라이브러리 유형 중 일부를 자연스럽게 받아들일 수 있습니다.
여기 또 다른 해결책이 있습니다.콤팩트하고 합리적으로 효율적입니다.
std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
tokens.push_back(text.substr(start, end - start));
start = end + 1;
}
tokens.push_back(text.substr(start));
return tokens;
}
문자열 구분기, 넓은 문자열 등을 쉽게 다룰 수 있도록 템플릿 제작이 가능합니다.
은 「」으로 하는 것에 해 주세요.""
의 빈 이 생성되어 분할됩니다.","
sep)는 두 의 빈 문자열이
빈 토큰을 건너뛰도록 쉽게 확장할 수도 있습니다.
std::vector<std::string> split(const std::string &text, char sep) {
std::vector<std::string> tokens;
std::size_t start = 0, end = 0;
while ((end = text.find(sep, start)) != std::string::npos) {
if (end != start) {
tokens.push_back(text.substr(start, end - start));
}
start = end + 1;
}
if (end != start) {
tokens.push_back(text.substr(start));
}
return tokens;
}
빈 토큰을 건너뛰면서 문자열을 여러 딜리미터로 분할하는 경우 다음 버전을 사용할 수 있습니다.
std::vector<std::string> split(const std::string& text, const std::string& delims)
{
std::vector<std::string> tokens;
std::size_t start = text.find_first_not_of(delims), end = 0;
while((end = text.find_first_of(delims, start)) != std::string::npos)
{
tokens.push_back(text.substr(start, end - start));
start = text.find_first_not_of(delims, end);
}
if(start != std::string::npos)
tokens.push_back(text.substr(start));
return tokens;
}
이것은 끈으로 반복하는 내가 좋아하는 방법이다.한 단어에 네가 원하는 것을 할 수 있어.
string line = "a line of text to iterate through";
string word;
istringstream iss(line, istringstream::in);
while( iss >> word )
{
// Do something on `word` here...
}
이것은 "Stack Overflow" 질문과 비슷합니다.C++에서 문자열을 토큰화하려면 어떻게 해야 합니까?Boost 외부 라이브러리 필요
#include <iostream>
#include <string>
#include <boost/tokenizer.hpp>
using namespace std;
using namespace boost;
int main(int argc, char** argv)
{
string text = "token test\tstring";
char_separator<char> sep(" \t");
tokenizer<char_separator<char>> tokens(text, sep);
for (const string& t : tokens)
{
cout << t << "." << endl;
}
}
결과를 벡터에 넣고 문자열을 구분자로 지원하며 빈 값을 유지할 수 있는 제어 기능을 제공하기 때문에 다음을 좋아합니다.근데 그땐 별로야.
#include <ostream>
#include <string>
#include <vector>
#include <algorithm>
#include <iterator>
using namespace std;
vector<string> split(const string& s, const string& delim, const bool keep_empty = true) {
vector<string> result;
if (delim.empty()) {
result.push_back(s);
return result;
}
string::const_iterator substart = s.begin(), subend;
while (true) {
subend = search(substart, s.end(), delim.begin(), delim.end());
string temp(substart, subend);
if (keep_empty || !temp.empty()) {
result.push_back(temp);
}
if (subend == s.end()) {
break;
}
substart = subend + delim.size();
}
return result;
}
int main() {
const vector<string> words = split("So close no matter how far", " ");
copy(words.begin(), words.end(), ostream_iterator<string>(cout, "\n"));
}
물론 Boost에는 이와 같이 부분적으로 동작하는 가 있습니다.그리고 만약 'white-space'라고 한다면, Boost의 분할을 사용하는 모든 유형의 공백 공간을 의미합니다.is_any_of()
잘 동작합니다.
STL에는 아직 사용 가능한 메서드가 없습니다.
단, 멤버를 사용하여 C의 함수를 사용할 수도 있고 직접 작성할 수도 있습니다.다음은 Google에서 빠르게 검색한 코드 샘플입니다('STL 문자열 분할').
void Tokenize(const string& str,
vector<string>& tokens,
const string& delimiters = " ")
{
// Skip delimiters at beginning.
string::size_type lastPos = str.find_first_not_of(delimiters, 0);
// Find first "non-delimiter".
string::size_type pos = str.find_first_of(delimiters, lastPos);
while (string::npos != pos || string::npos != lastPos)
{
// Found a token, add it to the vector.
tokens.push_back(str.substr(lastPos, pos - lastPos));
// Skip delimiters. Note the "not_of"
lastPos = str.find_first_not_of(delimiters, pos);
// Find next "non-delimiter"
pos = str.find_first_of(delimiters, lastPos);
}
}
출처: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html
코드 샘플에 대해 궁금한 점이 있으시면 댓글로 남겨주시면 설명해드리겠습니다.
, 「 」 「 」 「 」 「 」 「 」를하고 있지 않기 에,typedef
'라고 불리거나 '반복자'를 .<<
연산자는 그것이 나쁜 코드라는 것을 의미하지 않습니다.저는 C 함수를 꽤 자주 사용합니다.예를 들어, 둘 다 (대부분)보다 빠르고, 구문이 바이너리 타입에 훨씬 적합하며, EXE가 더 작아지는 경향이 있습니다.
이 "성능보다 뛰어난" 거래에 속지 마십시오.
다음은 분할 함수입니다.
- 범용
- 표준 C++ 사용(부스트 없음)
- 는 복수의 딜리미터를 사용할 수 있습니다.
빈 토큰을 무시합니다(쉽게 변경할 수 있습니다).
template<typename T> vector<T> split(const T & str, const T & delimiters) { vector<T> v; typename T::size_type start = 0; auto pos = str.find_first_of(delimiters, start); while(pos != T::npos) { if(pos != start) // ignore empty tokens v.emplace_back(str, start, pos - start); start = pos + 1; pos = str.find_first_of(delimiters, start); } if(start < str.length()) // ignore trailing delimiter v.emplace_back(str, start, str.length() - start); // add what's left of the string return v; }
사용 예:
vector<string> v = split<string>("Hello, there; World", ";,");
vector<wstring> v = split<wstring>(L"Hello, there; World", L";,");
이 문제에 대한 해결책은 다음 두 가지입니다.
char sep = ' ';
std::string s="1 This is an example";
for(size_t p=0, q=0; p!=s.npos; p=q)
std::cout << s.substr(p+(p!=0), (q=s.find(sep, p+1))-p-(p!=0)) << std::endl;
그러면 인쇄하는 대신 벡터에 넣을 수 있습니다.
또 다른 유연하고 빠른 방법
template<typename Operator>
void tokenize(Operator& op, const char* input, const char* delimiters) {
const char* s = input;
const char* e = s;
while (*e != 0) {
e = s;
while (*e != 0 && strchr(delimiters, *e) == 0) ++e;
if (e - s > 0) {
op(s, e - s);
}
s = e + 1;
}
}
문자열 벡터와 함께 사용하려면(편집: STL 클래스를 상속하지 않도록 누군가가 지적했으므로...hrmf;) :
template<class ContainerType>
class Appender {
public:
Appender(ContainerType& container) : container_(container) {;}
void operator() (const char* s, unsigned length) {
container_.push_back(std::string(s,length));
}
private:
ContainerType& container_;
};
std::vector<std::string> strVector;
Appender v(strVector);
tokenize(v, "A number of words to be tokenized", " \t");
바로 그거야!이것은 토큰라이저를 사용하는 방법 중 하나일 뿐입니다.예를 들어 단어를 세는 방법:
class WordCounter {
public:
WordCounter() : noOfWords(0) {}
void operator() (const char*, unsigned) {
++noOfWords;
}
unsigned noOfWords;
};
WordCounter wc;
tokenize(wc, "A number of words to be counted", " \t");
ASSERT( wc.noOfWords == 7 );
상상력에 의해 제한된다;)
다음은 표준 regex 라이브러리만 사용하는 간단한 솔루션입니다.
#include <regex>
#include <string>
#include <vector>
std::vector<string> Tokenize( const string str, const std::regex regex )
{
using namespace std;
std::vector<string> result;
sregex_token_iterator it( str.begin(), str.end(), regex, -1 );
sregex_token_iterator reg_end;
for ( ; it != reg_end; ++it ) {
if ( !it->str().empty() ) //token could be empty:check
result.emplace_back( it->str() );
}
return result;
}
regex 인수를 사용하면 여러 인수(스페이스, 쉼표 등)를 확인할 수 있습니다.
보통 공백과 쉼표로 분할하는 것만 선택하기 때문에 다음과 같은 기본 기능도 있습니다.
std::vector<string> TokenizeDefault( const string str )
{
using namespace std;
regex re( "[\\s,]+" );
return Tokenize( str, re );
}
"[\\s,]+"
(스페이스 체크)\\s
와 쉼표가 표시됩니다.,
를 참조해 주세요.
분할하는 「」를 해 주세요.wstring
string
,
std::regex
로로 합니다.std::wregex
sregex_token_iterator
로로 합니다.wsregex_token_iterator
컴파일러에 따라서는 string 인수를 참조할 수도 있습니다.
「」를 사용합니다.std::stringstream
당신은 완벽하게 일을 잘 해내고, 당신이 원하는 것을 정확히 할 수 있기 때문입니다.다만, 다른 방법을 찾고 있는 경우는, / 와 std::find_first_of()
를 사용할 수 있습니다.
다음은 예를 제시하겠습니다.
#include <iostream>
#include <string>
int main()
{
std::string s("Somewhere down the road");
std::string::size_type prev_pos = 0, pos = 0;
while( (pos = s.find(' ', pos)) != std::string::npos )
{
std::string substring( s.substr(prev_pos, pos-prev_pos) );
std::cout << substring << '\n';
prev_pos = ++pos;
}
std::string substring( s.substr(prev_pos, pos-prev_pos) ); // Last word
std::cout << substring << '\n';
return 0;
}
(앞으로 된 대부분의에서와 같이 ) 문자열 딜리미터로 에는 boost를 할 수 .boost_split_iterator
.
편리한 템플릿을 포함한 코드 예:
#include <iostream>
#include <vector>
#include <boost/algorithm/string.hpp>
template<typename _OutputIterator>
inline void split(
const std::string& str,
const std::string& delim,
_OutputIterator result)
{
using namespace boost::algorithm;
typedef split_iterator<std::string::const_iterator> It;
for(It iter=make_split_iterator(str, first_finder(delim, is_equal()));
iter!=It();
++iter)
{
*(result++) = boost::copy_range<std::string>(*iter);
}
}
int main(int argc, char* argv[])
{
using namespace std;
vector<string> splitted;
split("HelloFOOworldFOO!", "FOO", back_inserter(splitted));
// or directly to console, for example
split("HelloFOOworldFOO!", "FOO", ostream_iterator<string>(cout, "\n"));
return 0;
}
표준 regex 라이브러리만 사용하는 regex 솔루션을 소개합니다. (제가 조금 녹슬어서 구문 오류가 있을 수 있지만, 적어도 이것은 일반적인 아이디어입니다.)
#include <regex.h>
#include <string.h>
#include <vector.h>
using namespace std;
vector<string> split(string s){
regex r ("\\w+"); //regex matches whole words, (greedy, so no fragment words)
regex_iterator<string::iterator> rit ( s.begin(), s.end(), r );
regex_iterator<string::iterator> rend; //iterators to iterate thru words
vector<string> result<regex_iterator>(rit, rend);
return result; //iterates through the matches to fill the vector
}
라는 이름의 함수가 있습니다.
#include<string>
using namespace std;
vector<string> split(char* str,const char* delim)
{
char* saveptr;
char* token = strtok_r(str,delim,&saveptr);
vector<string> result;
while(token != NULL)
{
result.push_back(token);
token = strtok_r(NULL,delim,&saveptr);
}
return result;
}
은 드디어 C++20으로 합니다.split
기능.오히려 레인지 어댑터입니다.Godbolt 링크
#include <iostream>
#include <ranges>
#include <string_view>
namespace ranges = std::ranges;
namespace views = std::views;
using str = std::string_view;
auto view =
"Multiple words"
| views::split(' ')
| views::transform([](auto &&r) -> str {
return str(r.begin(), r.end());
});
auto main() -> int {
for (str &&sv : view) {
std::cout << sv << '\n';
}
}
「」를 사용합니다.std::string_view
의 ★★★★★★★★★★★★★★★★★★★★★★★★★」range-v3
★★★★★★★★★★★★★★★★★★:
https://wandbox.org/permlink/kW5lwRCL1pxjp2pW
#include <iostream>
#include <string>
#include <string_view>
#include "range/v3/view.hpp"
#include "range/v3/algorithm.hpp"
int main() {
std::string s = "Somewhere down the range v3 library";
ranges::for_each(s
| ranges::view::split(' ')
| ranges::view::transform([](auto &&sub) {
return std::string_view(&*sub.begin(), ranges::distance(sub));
}),
[](auto s) {std::cout << "Substring: " << s << "\n";}
);
}
" " " 를 for
ranges::for_each
★★★★★★★★★★★★★★★★★★:
#include <iostream>
#include <string>
#include <string_view>
#include "range/v3/view.hpp"
int main()
{
std::string str = "Somewhere down the range v3 library";
for (auto s : str | ranges::view::split(' ')
| ranges::view::transform([](auto&& sub) { return std::string_view(&*sub.begin(), ranges::distance(sub)); }
))
{
std::cout << "Substring: " << s << "\n";
}
}
공백 이외의 기호로 문자열을 해석해야 할 경우 문자열 스트림이 편리할 수 있습니다.
string s = "Name:JAck; Spouse:Susan; ...";
string dummy, name, spouse;
istringstream iss(s);
getline(iss, dummy, ':');
getline(iss, name, ';');
getline(iss, dummy, ':');
getline(iss, spouse, ';')
지금까지는 Boost에 있는 것을 사용했지만, 거기에 의존하지 않는 것이 필요했기 때문에, 다음과 같이 하게 되었습니다.
static void Split(std::vector<std::string>& lst, const std::string& input, const std::string& separators, bool remove_empty = true)
{
std::ostringstream word;
for (size_t n = 0; n < input.size(); ++n)
{
if (std::string::npos == separators.find(input[n]))
word << input[n];
else
{
if (!word.str().empty() || !remove_empty)
lst.push_back(word.str());
word.str("");
}
}
if (!word.str().empty() || !remove_empty)
lst.push_back(word.str());
}
은 에 separators
둘 이상의 문자를 전달할 수 있습니다.
짧고 우아함
#include <vector>
#include <string>
using namespace std;
vector<string> split(string data, string token)
{
vector<string> output;
size_t pos = string::npos; // size_t to avoid improbable overflow
do
{
pos = data.find(token);
output.push_back(data.substr(0, pos));
if (string::npos != pos)
data = data.substr(pos + token.size());
} while (string::npos != pos);
return output;
}
는 임의의 문자열을 딜리미터로 사용할 수 있으며 바이너리 데이터에도 사용할 수 있습니다(std:: 문자열은 늘을 포함한 바이너리 데이터를 지원합니다).
사용:
auto a = split("this!!is!!!example!string", "!!");
출력:
this
is
!example!string
스트로톡을 이용해서 직접 굴려보고 끈을 끊는 부스트도 써봤어요.제가 찾은 가장 좋은 방법은 C++ String Toolkit Library입니다.그것은 믿을 수 없을 정도로 유연하고 빠르다.
#include <iostream>
#include <vector>
#include <string>
#include <strtk.hpp>
const char *whitespace = " \t\r\n\f";
const char *whitespace_and_punctuation = " \t\r\n\f;,=";
int main()
{
{ // normal parsing of a string into a vector of strings
std::string s("Somewhere down the road");
std::vector<std::string> result;
if( strtk::parse( s, whitespace, result ) )
{
for(size_t i = 0; i < result.size(); ++i )
std::cout << result[i] << std::endl;
}
}
{ // parsing a string into a vector of floats with other separators
// besides spaces
std::string s("3.0, 3.14; 4.0");
std::vector<float> values;
if( strtk::parse( s, whitespace_and_punctuation, values ) )
{
for(size_t i = 0; i < values.size(); ++i )
std::cout << values[i] << std::endl;
}
}
{ // parsing a string into specific variables
std::string s("angle = 45; radius = 9.9");
std::string w1, w2;
float v1, v2;
if( strtk::parse( s, whitespace_and_punctuation, w1, v1, w2, v2) )
{
std::cout << "word " << w1 << ", value " << v1 << std::endl;
std::cout << "word " << w2 << ", value " << v2 << std::endl;
}
}
return 0;
}
이 툴킷은 이 간단한 예에서 보여지는 것보다 훨씬 유연하지만 문자열을 유용한 요소로 해석하는 데 있어 그 효용성은 놀랍습니다.
이 답변은 문자열을 문자열의 벡터에 넣습니다.부스트 라이브러리를 사용합니다.
#include <boost/algorithm/string.hpp>
std::vector<std::string> strs;
boost::split(strs, "string to split", boost::is_any_of("\t "));
끈과 C 기반의 끈을 쉽게 나눌 수 있는 방법이 필요해서 만든 거예요.다른 누군가도 유용하게 사용할 수 있기를 바랍니다.또한 토큰에 의존하지 않고 필드를 구분자로 사용할 수 있습니다.그것도 제가 필요했던 키입니다.
한층 더 우아함을 향상시킬 수 있는 개선책이 있다고 생각합니다만, 꼭 부탁드립니다.
String Splitter.hpp:
#include <vector>
#include <iostream>
#include <string.h>
using namespace std;
class StringSplit
{
private:
void copy_fragment(char*, char*, char*);
void copy_fragment(char*, char*, char);
bool match_fragment(char*, char*, int);
int untilnextdelim(char*, char);
int untilnextdelim(char*, char*);
void assimilate(char*, char);
void assimilate(char*, char*);
bool string_contains(char*, char*);
long calc_string_size(char*);
void copy_string(char*, char*);
public:
vector<char*> split_cstr(char);
vector<char*> split_cstr(char*);
vector<string> split_string(char);
vector<string> split_string(char*);
char* String;
bool do_string;
bool keep_empty;
vector<char*> Container;
vector<string> ContainerS;
StringSplit(char * in)
{
String = in;
}
StringSplit(string in)
{
size_t len = calc_string_size((char*)in.c_str());
String = new char[len + 1];
memset(String, 0, len + 1);
copy_string(String, (char*)in.c_str());
do_string = true;
}
~StringSplit()
{
for (int i = 0; i < Container.size(); i++)
{
if (Container[i] != NULL)
{
delete[] Container[i];
}
}
if (do_string)
{
delete[] String;
}
}
};
StringSplitter.cpp:
#include <string.h>
#include <iostream>
#include <vector>
#include "StringSplit.hpp"
using namespace std;
void StringSplit::assimilate(char*src, char delim)
{
int until = untilnextdelim(src, delim);
if (until > 0)
{
char * temp = new char[until + 1];
memset(temp, 0, until + 1);
copy_fragment(temp, src, delim);
if (keep_empty || *temp != 0)
{
if (!do_string)
{
Container.push_back(temp);
}
else
{
string x = temp;
ContainerS.push_back(x);
}
}
else
{
delete[] temp;
}
}
}
void StringSplit::assimilate(char*src, char* delim)
{
int until = untilnextdelim(src, delim);
if (until > 0)
{
char * temp = new char[until + 1];
memset(temp, 0, until + 1);
copy_fragment(temp, src, delim);
if (keep_empty || *temp != 0)
{
if (!do_string)
{
Container.push_back(temp);
}
else
{
string x = temp;
ContainerS.push_back(x);
}
}
else
{
delete[] temp;
}
}
}
long StringSplit::calc_string_size(char* _in)
{
long i = 0;
while (*_in++)
{
i++;
}
return i;
}
bool StringSplit::string_contains(char* haystack, char* needle)
{
size_t len = calc_string_size(needle);
size_t lenh = calc_string_size(haystack);
while (lenh--)
{
if (match_fragment(haystack + lenh, needle, len))
{
return true;
}
}
return false;
}
bool StringSplit::match_fragment(char* _src, char* cmp, int len)
{
while (len--)
{
if (*(_src + len) != *(cmp + len))
{
return false;
}
}
return true;
}
int StringSplit::untilnextdelim(char* _in, char delim)
{
size_t len = calc_string_size(_in);
if (*_in == delim)
{
_in += 1;
return len - 1;
}
int c = 0;
while (*(_in + c) != delim && c < len)
{
c++;
}
return c;
}
int StringSplit::untilnextdelim(char* _in, char* delim)
{
int s = calc_string_size(delim);
int c = 1 + s;
if (!string_contains(_in, delim))
{
return calc_string_size(_in);
}
else if (match_fragment(_in, delim, s))
{
_in += s;
return calc_string_size(_in);
}
while (!match_fragment(_in + c, delim, s))
{
c++;
}
return c;
}
void StringSplit::copy_fragment(char* dest, char* src, char delim)
{
if (*src == delim)
{
src++;
}
int c = 0;
while (*(src + c) != delim && *(src + c))
{
*(dest + c) = *(src + c);
c++;
}
*(dest + c) = 0;
}
void StringSplit::copy_string(char* dest, char* src)
{
int i = 0;
while (*(src + i))
{
*(dest + i) = *(src + i);
i++;
}
}
void StringSplit::copy_fragment(char* dest, char* src, char* delim)
{
size_t len = calc_string_size(delim);
size_t lens = calc_string_size(src);
if (match_fragment(src, delim, len))
{
src += len;
lens -= len;
}
int c = 0;
while (!match_fragment(src + c, delim, len) && (c < lens))
{
*(dest + c) = *(src + c);
c++;
}
*(dest + c) = 0;
}
vector<char*> StringSplit::split_cstr(char Delimiter)
{
int i = 0;
while (*String)
{
if (*String != Delimiter && i == 0)
{
assimilate(String, Delimiter);
}
if (*String == Delimiter)
{
assimilate(String, Delimiter);
}
i++;
String++;
}
String -= i;
delete[] String;
return Container;
}
vector<string> StringSplit::split_string(char Delimiter)
{
do_string = true;
int i = 0;
while (*String)
{
if (*String != Delimiter && i == 0)
{
assimilate(String, Delimiter);
}
if (*String == Delimiter)
{
assimilate(String, Delimiter);
}
i++;
String++;
}
String -= i;
delete[] String;
return ContainerS;
}
vector<char*> StringSplit::split_cstr(char* Delimiter)
{
int i = 0;
size_t LenDelim = calc_string_size(Delimiter);
while(*String)
{
if (!match_fragment(String, Delimiter, LenDelim) && i == 0)
{
assimilate(String, Delimiter);
}
if (match_fragment(String, Delimiter, LenDelim))
{
assimilate(String,Delimiter);
}
i++;
String++;
}
String -= i;
delete[] String;
return Container;
}
vector<string> StringSplit::split_string(char* Delimiter)
{
do_string = true;
int i = 0;
size_t LenDelim = calc_string_size(Delimiter);
while (*String)
{
if (!match_fragment(String, Delimiter, LenDelim) && i == 0)
{
assimilate(String, Delimiter);
}
if (match_fragment(String, Delimiter, LenDelim))
{
assimilate(String, Delimiter);
}
i++;
String++;
}
String -= i;
delete[] String;
return ContainerS;
}
예:
int main(int argc, char*argv[])
{
StringSplit ss = "This:CUT:is:CUT:an:CUT:example:CUT:cstring";
vector<char*> Split = ss.split_cstr(":CUT:");
for (int i = 0; i < Split.size(); i++)
{
cout << Split[i] << endl;
}
return 0;
}
유언 출력:
이것.
이
한 사람
예
문자열
int main(int argc, char*argv[])
{
StringSplit ss = "This:is:an:example:cstring";
vector<char*> Split = ss.split_cstr(':');
for (int i = 0; i < Split.size(); i++)
{
cout << Split[i] << endl;
}
return 0;
}
int main(int argc, char*argv[])
{
string mystring = "This[SPLIT]is[SPLIT]an[SPLIT]example[SPLIT]string";
StringSplit ss = mystring;
vector<string> Split = ss.split_string("[SPLIT]");
for (int i = 0; i < Split.size(); i++)
{
cout << Split[i] << endl;
}
return 0;
}
int main(int argc, char*argv[])
{
string mystring = "This|is|an|example|string";
StringSplit ss = mystring;
vector<string> Split = ss.split_string('|');
for (int i = 0; i < Split.size(); i++)
{
cout << Split[i] << endl;
}
return 0;
}
빈 엔트리를 유지하려면(기본적으로 빈 엔트리는 제외됩니다)
StringSplit ss = mystring;
ss.keep_empty = true;
vector<string> Split = ss.split_string(":DELIM:");
목적은 C#의 Split() 메서드와 유사하게 하는 것입니다.이 메서드는 스트링 분할이 간단합니다.
String[] Split =
"Hey:cut:what's:cut:your:cut:name?".Split(new[]{":cut:"}, StringSplitOptions.None);
foreach(String X in Split)
{
Console.Write(X);
}
다른 사람도 나만큼 유용하게 썼으면 좋겠어.
다른 방법이 있어요
void split_string(string text,vector<string>& words)
{
int i=0;
char ch;
string word;
while(ch=text[i++])
{
if (isspace(ch))
{
if (!word.empty())
{
words.push_back(word);
}
word = "";
}
else
{
word += ch;
}
}
if (!word.empty())
{
words.push_back(word);
}
}
이건 어때?
#include <string>
#include <vector>
using namespace std;
vector<string> split(string str, const char delim) {
vector<string> v;
string tmp;
for(string::const_iterator i; i = str.begin(); i <= str.end(); ++i) {
if(*i != delim && i != str.end()) {
tmp += *i;
} else {
v.push_back(tmp);
tmp = "";
}
}
return v;
}
boost/regex 메서드는 분할 기준을 지정할 수 있는 최대의 유연성을 제공하기 때문에 이 작업에 사용하는 것이 좋습니다.
#include <iostream>
#include <string>
#include <boost/regex.hpp>
int main() {
std::string line("A:::line::to:split");
const boost::regex re(":+"); // one or more colons
// -1 means find inverse matches aka split
boost::sregex_token_iterator tokens(line.begin(),line.end(),re,-1);
boost::sregex_token_iterator end;
for (; tokens != end; ++tokens)
std::cout << *tokens << std::endl;
}
최근에 나는 낙타 케이스를 넣은 단어를 하위 단어로 나누어야 했다.딜리미터는 없고 대문자는 사용할 수 없습니다.
#include <string>
#include <list>
#include <locale> // std::isupper
template<class String>
const std::list<String> split_camel_case_string(const String &s)
{
std::list<String> R;
String w;
for (String::const_iterator i = s.begin(); i < s.end(); ++i) { {
if (std::isupper(*i)) {
if (w.length()) {
R.push_back(w);
w.clear();
}
}
w += *i;
}
if (w.length())
R.push_back(w);
return R;
}
예를 들어, "는 분할됩니다.AQuery를 "A", "Query" 및 "Trades"로 변경합니다.이 함수는 좁고 넓은 문자열로 작동합니다.현재의 로케일을 존중하기 때문에, 「라움파흐트 위버와충스 베로르드엉」을 「라움파흐트」, 「위버와충스」, 「베로드엉」으로 분할합니다.
메모std::upper
function template 인수로 전달해야 합니다.그러면 이 함수에서 더 일반화된 함수는 다음과 같은 구분 기호로 분할될 수 있습니다.","
,";"
★★★★★★★★★★★★★★★★★」" "
언급URL : https://stackoverflow.com/questions/236129/how-do-i-iterate-over-the-words-of-a-string
'programing' 카테고리의 다른 글
신속한 언어로 구조화 vs 클래스 (0) | 2023.04.16 |
---|---|
데이터베이스에 저장된 모든 프로시저에 대해 사용자에게 실행 권한을 부여하시겠습니까? (0) | 2023.04.16 |
std::목록을 반복하는 동안 목록에서 요소를 제거할 수 있습니까? (0) | 2023.04.16 |
이중 괄호 또는 단일 괄호, 괄호, 컬리 괄호 사용 방법 (0) | 2023.04.16 |
시트가 있는지 테스트 또는 확인 (0) | 2023.04.16 |