C++快速分割字符串

C++中有一个函数可以快速分割字符串,它也是C库中的函数——strtok,用它分割字符串与C#、Delphi分割字符串一样方便了。这里引用一段strtok用法:
The strtok() function returns a pointer to the next "token" in str1, where str2 contains the delimiters that determine the token. strtok() returns NULL if no token is found. In order to convert a string to tokens, the first call to strtok() should have str1 point to the string to be tokenized. All calls after this should have str1 beNULL.

For example:
   char str[] = "now # is the time for all # good men to come to the # aid of their country";
   char delims[] = "#";
   char *result = NULL;
   result = strtok( str, delims );
   while( result != NULL ) {
       printf( "result is \"%s\"\n", result );
       result = strtok( NULL, delims );
   }            

The above code will display the following output:

   result is "now "
   result is " is the time for all "
   result is " good men to come to the "
   result is " aid of their country"
分割的字符串可以是多个如:
char str[] = "The above#code|will display,the following output"
char delims[] = ",|# " ;
输出为:
The 
above
code
will 
display
the
following
output
注:慎用“\"做分割符,这个不用多解释吧!

<think>嗯,用户之前问过关于字符串拆分的问题,现在具体问的是C++字符串分割函数。我需要回顾一下之前的回答,确保这次的内容不重复,并且更深入针对C++。 首先,用户可能需要了解如何在C++中实现字符串分割,因为标准库没有直接提供这个函数。之前的回答提到了两种方法:使用stringstream和getline,以及手动遍历字符串。我需要详细展开这两种方法,并可能添加更多例子或注意事项。 用户可能对效率有要求,特别是处理大字符串或高频调用时,所以可以补充关于性能优化的部分,比如使用reserve预分配内存,或者避免不必要的拷贝。 另外,用户可能遇到不同的分隔符情况,比如多字符分隔符或正则表达式,需要进一步说明如何处理这些情况,比如使用C++11的正则表达式库或者Boost库。 还要注意错误处理和边缘情况,比如空字符串、连续分隔符、开头或结尾的分隔符等,提供解决方案,比如过滤空结果。 可能用户需要现成的代码示例,可以直接复制使用,所以代码部分要清晰,注释详细,并给出不同场景下的应用示例,比如分割空格、逗号、多字符分隔符等。 最后,比较不同方法的优缺点,帮助用户根据具体情况选择合适的方法,比如标准方法简单但功能有限,正则表达式强大但可能有性能开销,手动实现灵活但代码较多,Boost库方便但需要额外安装。 需要确保回答结构清晰,分点说明,让用户逐步理解实现方法,注意事项,以及应用场景。同时检查LaTeX格式是否正确,代码语法无误,用中文解释清楚每个步骤。</think>### **C++ 字符串分割函数** 在 C++ 标准库中,没有直接提供字符串分割函数,但可以通过手动实现或结合现有工具实现。以下是多种实现方法及详细说明: --- ### **1. 基础方法:使用 `std::istringstream` 和 `getline`** **适用场景**:按单字符分隔符(如空格、逗号)拆分字符串。 **代码示例**: ```cpp #include <sstream> #include <vector> #include <string> std::vector<std::string> split(const std::string& s, char delimiter) { std::vector<std::string> tokens; std::string token; std::istringstream iss(s); // 将字符串转换为输入流 while (std::getline(iss, token, delimiter)) { // 按分隔符读取子串 if (!token.empty()) { // 可选:跳过空字符串 tokens.push_back(token); } } return tokens; } // 示例:拆分 "apple,banana,orange"(分隔符为 ',') // 输出:["apple", "banana", "orange"] ``` **特点**: - **简单高效**:适用于单字符分隔符。 - **空字符串处理**:若连续分隔符(如 `"a,,b"`),会生成空字符串,可通过 `if (!token.empty())` 过滤。 --- ### **2. 手动遍历字符串:处理多字符分隔符** **适用场景**:分隔符为多字符(如 `"##"`)或需要更灵活的控制。 **代码示例**: ```cpp #include <vector> #include <string> std::vector<std::string> split(const std::string& s, const std::string& delimiter) { std::vector<std::string> tokens; size_t start = 0; size_t end = s.find(delimiter); // 查找第一个分隔符位置 while (end != std::string::npos) { tokens.push_back(s.substr(start, end - start)); // 提取子串 start = end + delimiter.length(); // 跳过分隔符 end = s.find(delimiter, start); // 继续查找下一个分隔符 } tokens.push_back(s.substr(start)); // 添加最后一个子串 return tokens; } // 示例:拆分 "a##b##c"(分隔符为 "##") // 输出:["a", "b", "c"] ``` **特点**: - **支持多字符分隔符**:如 `"##"`、`"<sep>"` 等。 - **可控性强**:可灵活处理边缘情况(如开头/结尾的分隔符)。 --- ### **3. 使用正则表达式(C++11 及以上)** **适用场景**:复杂分隔符(如多个不同符号组合)。 **代码示例**: ```cpp #include <regex> #include <vector> #include <string> std::vector<std::string> split_regex(const std::string& s, const std::string& pattern) { std::regex re(pattern); std::sregex_token_iterator it(s.begin(), s.end(), re, -1); // 按正则拆分 std::sregex_token_iterator end; std::vector<std::string> tokens(it, end); // 过滤空字符串(可选) tokens.erase(std::remove_if(tokens.begin(), tokens.end(), [](const std::string& str) { return str.empty(); }), tokens.end()); return tokens; } // 示例:按逗号或分号拆分 "apple;banana,orange" // 调用:split_regex("apple;banana,orange", "[,;]+") // 输出:["apple", "banana", "orange"] ``` **特点**: - **灵活性强**:支持正则表达式(如 `[,\\s]+` 表示逗号或空格)。 - **性能开销**:正则表达式编译较慢,高频调用时需预编译模式。 --- ### **4. 使用 Boost 库** **适用场景**:需要高效、简洁的分割函数(需安装 Boost)。 **代码示例**: ```cpp #include <boost/algorithm/string.hpp> #include <vector> #include <string> std::vector<std::string> split_boost(const std::string& s, const std::string& delimiter) { std::vector<std::string> tokens; boost::split(tokens, s, boost::is_any_of(delimiter)); // 按分隔符集合拆分 return tokens; } // 示例:拆分 "apple|banana|orange"(分隔符为 "|") // 输出:["apple", "banana", "orange"] ``` **特点**: - **简洁高效**:单行代码实现复杂拆分。 - **依赖 Boost**:需额外安装库。 --- ### **5. 关键问题与优化** 1. **性能优化**: - **预分配内存**:使用 `tokens.reserve(n)` 减少 `vector` 动态扩容开销。 - **避免拷贝**:对超长字符串,使用 `string_view`(C++17)减少拷贝。 2. **边缘情况处理**: - **空输入**:检查输入字符串是否为空。 - **连续分隔符**:决定是否保留空字符串(如 `"a,,b"` 是否拆分为 `["a", "", "b"]`)。 3. **返回值设计**: - 返回 `vector<string>` 是最常见方式,也可通过引用参数传递结果。 --- ### **6. 完整示例:综合实现** ```cpp #include <vector> #include <string> #include <sstream> #include <algorithm> // 综合函数:支持单字符和多字符分隔符,可选是否跳过空字符串 std::vector<std::string> split(const std::string& s, const std::string& delimiter, bool skip_empty = true) { std::vector<std::string> tokens; size_t start = 0, end = 0; while ((end = s.find(delimiter, start)) != std::string::npos) { std::string token = s.substr(start, end - start); if (!(skip_empty && token.empty())) { tokens.push_back(token); } start = end + delimiter.length(); } // 处理最后一个子串 std::string token = s.substr(start); if (!(skip_empty && token.empty())) { tokens.push_back(token); } return tokens; } // 示例:拆分 "##apple####banana##orange##"(分隔符为 "##",跳过空) // 输出:["apple", "banana", "orange"] ``` --- ### **总结** 在 C++ 中实现字符串分割的核心方法包括: - **`istringstream` + `getline`**:简单高效,适合单字符分隔符。 - **手动遍历**:灵活支持多字符分隔符。 - **正则表达式**:处理复杂模式,但需注意性能。 - **Boost 库**:快速实现,但依赖外部库。 根据需求选择合适方法,重点关注 **分隔符类型**、**空值处理** 和 **性能要求**。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值