2009-03-01 116 views
19

cũng có ở đó không? bởi chuỗi tôi có nghĩa là std :: stringCó cách tích hợp để tách chuỗi trong C++ không?

+5

http://stackoverflow.com/questions/236129/c-how-to-split-a-string – sykora

+3

Nhiều như tôi yêu C++, tôi vẫn ghét cong vênh tâm trí của mình xung quanh dây của nó. – pyon

+0

ah đúng. trông giống như một câu hỏi trùng lặp. tôi khuyên bạn nên đóng cái này và chuyển hướng mọi người đến "c-how-to-split-a-string" khác.bạn nghĩ sao? –

Trả lời

-2

C chuỗi

Đơn giản chỉ cần chèn một \0 nơi bạn muốn chia nhỏ. Đây là về như được xây dựng trong như bạn có thể nhận được với các chức năng C tiêu chuẩn.

Chức năng này tách trên lần xuất hiện đầu tiên của bộ phân cách char, trả về chuỗi thứ hai.

char *split_string(char *str, char separator) { 
    char *second = strchr(str, separator); 
    if(second == NULL) 
     return NULL; 

    *second = '\0'; 
    ++second; 
    return second; 
} 
+0

tại sao không sử dụng strtok()? – cdonner

+0

@cdonner, Vì strchr đơn giản hơn. =] – strager

+1

@strager: Đây là thiết kế kém - sửa đổi đầu vào. Mặc dù đây là thứ mà strtok() đang làm và đã bỏ đi. – dirkgently

1

Câu trả lời là không. Bạn phải phá vỡ chúng bằng cách sử dụng một trong các chức năng thư viện.

Something tôi sử dụng:

std::vector<std::string> parse(std::string l, char delim) 
{ 
    std::replace(l.begin(), l.end(), delim, ' '); 
    std::istringstream stm(l); 
    std::vector<std::string> tokens; 
    for (;;) { 
     std::string word; 
     if (!(stm >> word)) break; 
     tokens.push_back(word); 
    } 
    return tokens; 
} 

Bạn cũng có thể xem xét phương pháp basic_streambuf<T>::underflow() và viết một bộ lọc.

+0

tôi đã chỉnh sửa để chỉ định, i ment std :: string –

7

STL chuỗi

Bạn có thể sử dụng lặp chuỗi để làm công việc bẩn thỉu của mình.

std::string str = "hello world"; 

std::string::const_iterator pos = std::find(string.begin(), string.end(), ' '); // Split at ' '. 

std::string left(str.begin(), pos); 
std::string right(pos + 1, str.end()); 

// Echoes "hello|world". 
std::cout << left << "|" << right << std::endl; 
+0

Điều này có thể áp dụng cho chuỗi hai từ không? –

3
void split(string StringToSplit, string Separators) 
{ 
    size_t EndPart1 = StringToSplit.find_first_of(Separators) 
    string Part1 = StringToSplit.substr(0, EndPart1); 
    string Part2 = StringToSplit.substr(EndPart1 + 1); 
} 
+0

cảm ơn, nếu điều này kết thúc trong một số chương trình mã nguồn mở một nơi nào đó, tôi sẽ cần phải cung cấp cho bạn tín dụng :) –

11

Không có cách nào tích hợp để tách một chuỗi trong C++, nhưng boost cung cấp string algo thư viện để làm tất cả các loại thao tác chuỗi, bao gồm chuỗi splitting.

18

Dưới đây là một chức năng chia perl-phong cách tôi sử dụng:

void split(const string& str, const string& delimiters , vector<string>& tokens) 
{ 
    // 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); 
    } 
} 
+0

Tôi thích giải pháp này. Không giống như hầu hết các giải pháp khác, nó không yêu cầu tăng cường, kết hợp các dấu phân tách, hỗ trợ nhiều dấu phân cách, được viết thành tài liệu và khá nhỏ gọn và dễ hiểu đối với các noobs như tôi. Tôi chỉ cần thay đổi tham số delimeters để có một mặc định, như trong bản gốc: http://oopweb.com/CPP/Documents/CPPHOWTO/Volume/C++Programming-HOWTO-7.html :-) – JJC

+0

Ngoài ra, Noobs như tôi nên cẩn thận để xóa các vector mỗi khi họ gọi chức năng này nếu họ mong đợi nó chỉ giữ bộ cuối cùng của thẻ! (sử dụng tokens.clear()). – JJC

+1

Chuỗi cũ hiển thị trong tìm kiếm. Tôi sẽ thay đổi chữ ký của 'split' thành không có tham số thứ ba, và trả về' vector 'thay vào đó (' tokens' sẽ là biến cục bộ). –

0

Cái quái gì ... Đây là phiên bản của tôi ...

Lưu ý: Tách trên ("XZaaaXZ", "XZ") sẽ cung cấp cho bạn 3 chuỗi. 2 trong số các chuỗi đó sẽ trống và sẽ không được thêm vàoStringVector nếu theIncludeEmptyStrings là sai.

Dấu phân tách là không bất kỳ phần tử nào trong tập hợp, mà đúng hơn là khớp với chuỗi chính xác đó.

inline void 
StringSplit(vector<string> * theStringVector, /* Altered/returned value */ 
      const string & theString, 
      const string & theDelimiter, 
      bool    theIncludeEmptyStrings = false) 
{ 
    UASSERT(theStringVector, !=, (vector<string> *) NULL); 
    UASSERT(theDelimiter.size(), >, 0); 

    size_t start = 0, end = 0, length = 0; 

    while (end != string::npos) 
    { 
    end = theString.find(theDelimiter, start); 

     // If at end, use length=maxLength. Else use length=end-start. 
    length = (end == string::npos) ? string::npos : end - start; 

    if ( theIncludeEmptyStrings 
     || ( (length > 0) /* At end, end == length == string::npos */ 
      && (start < theString.size()))) 
     theStringVector -> push_back(theString.substr(start, length)); 

     // If at end, use start=maxSize. Else use start=end+delimiter. 
    start = ( (end > (string::npos - theDelimiter.size())) 
       ? string::npos : end + theDelimiter.size() ); 
    } 
} 


inline vector<string> 
StringSplit(const string & theString, 
      const string & theDelimiter, 
      bool    theIncludeEmptyStrings = false) 
{ 
    vector<string> v; 
    StringSplit(& v, theString, theDelimiter, theIncludeEmptyStrings); 
    return v; 
} 
-2

Phương pháp khá đơn giản là sử dụng phương thức c_str() của std :: string để lấy mảng ký tự kiểu C, sau đó sử dụng strtok() để mã hóa chuỗi. Không phải là hùng hồn như một số giải pháp khác được liệt kê ở đây, nhưng nó dễ dàng và hoạt động.

+2

strtok ghi vào bộ nhớ được trỏ tới. c_str() trỏ tới bộ nhớ mà không được ghi vào (bất biến của lớp chuỗi - có thể âm thầm phá vỡ những thứ như ngữ nghĩa sao chép trên ghi). tiêu chuẩn C++ cấm nó. u có thể sao chép vào một std :: vector đầu tiên, sau đó bạn có thể sử dụng strtok mặc dù. –

+0

Phương thức c_str trả về một chuỗi const trỏ đến biểu diễn bên trong. Đó là const vì vậy bạn cũng phải strdup nó hoặc sao chép nó vào một vector. Một cách C++ đã được yêu cầu vì vậy tôi downvoting này. – Matt

10

Yup, chuỗi.

std::istringstream oss(std::string("This is a test string")); 
std::string word; 
while(oss >> word) { 
    std::cout << "[" << word << "] "; 
} 
+0

Nó phải là istringstream. – cpx

+0

@ Dave18: cảm ơn – MSalters

+3

Đây là bộ chia công việc-ngựa của tôi. Nếu bạn muốn phân tách trên dấu phân cách, bạn chỉ có thể thay thế 'oss >> từ' bằng' getline (oss, word, ':') ' – Eponymous

0

Không có cách nào phổ biến làm việc này.

Tôi thích số boost::tokenizer, tiêu đề của nó chỉ và dễ sử dụng.

Các vấn đề liên quan