c语言字符串定界符,关于c ++:按字符分割字符串
我知道这是一个非常简单的问题,但我只想一次为自己解决
我只想使用字符作为分割定界符将字符串分割成数组。 (很像C#著名的.Split()函数。我当然可以应用蛮力方法,但是我想知道是否有什么更好的方法了。)
到目前为止,我已经搜索过,也许最接近的解决方案是使用strtok(),但是由于不方便(将字符串转换为char数组等),我不喜欢使用它。有没有更简单的方法来实现这一目标?
注意:我想强调这一点,因为人们可能会问:"蛮力为什么不起作用"。我的暴力解决方案是创建一个循环,并在其中使用substr()函数。但是,由于它需要起点和长度,因此在我想分割日期时会失败。因为用户可能输入的时间是2012年7月12日或2011年7月3日,所以在计算" /"定界符的下一个位置之前,我可以真正说出长度。
拆分字符串C ++的可能重复项
使用向量,字符串和stringstream。有点麻烦,但可以解决问题。
std::stringstream test("this_is_a_test_string");
std::string segment;
std::vector<:string> seglist;
while(std::getline(test, segment, '_'))
{
seglist.push_back(segment);
}
导致向量的内容与
std::vector<:string> seglist{"this","is","a","test","string" };
实际上,这种方法正是我所寻找的。很容易理解,不使用外部库,只是非常简单。谢谢@thelazydeveloper!
如果要提高性能,可以添加seglist.reserve(std::count_if(str.begin(), str.end(), [&](char c) { return c == splitChar; }) + (str.empty() ? 1 : 0));如果要拆分的原始字符串存储在str中。
喜欢RegEx的人的另一种方式(C ++ 11 / boost)。就我个人而言,我非常喜欢RegEx这类数据。 IMO比使用分隔符简单地分割字符串要强大得多,因为您可以根据需要选择对构成"有效"数据的内容更加了解。
#include
#include // copy
#include // back_inserter
#include // regex, sregex_token_iterator
#include
int main()
{
std::string str ="08/04/2012";
std::vector<:string> tokens;
std::regex re("\\d+");
//start/end points of tokens in str
std::sregex_token_iterator
begin(str.begin(), str.end(), re),
end;
std::copy(begin, end, std::back_inserter(tokens));
}
因此,您可以在代码中包括整个正则表达式匹配器,仅用于拆分字符串。伤心...
@Dev否,包括一个正则表达式匹配器,以便对构成有效数据的内容更加智能-例如选择数字,并允许使用其他分隔符,例如点或连字符
就二进制大小和整体效率而言,这都是不好的,但是由于这两个原因都不涉及这种情况,因此我不再继续。
@Dev如果一个人对二进制大小有如此极端的约束,那么他们甚至应该重新考虑使用C ++,或者至少使用它的标准库(例如string / vector / etc),因为它们都会产生类似的效果。关于效率,最好的建议来自Donald Knuth-"过早的优化是万恶之源";换句话说,在进行优化之前,首要任务是确定是否存在问题,然后通过诸如剖析之类的客观手段来确定原因,而不是浪费时间试图寻找每一个可能的微观优化。
"在这种情况下,两个人都不关心"-我自己。
@Dev然后我想知道什至提起它们的目的是什么。
我只是不想将整个正则表达式引擎用于查找整数。但是,如果您不想专门化代码,这很好。
Boost具有您要在algorithm/string.hpp中查找的split():
std::string sample ="07/3/2011";
std::vector strs;
boost::split(strs, sample, boost::is_any_of("/"));
另一种可能性是使流具有使用特殊ctype构面的语言环境。流使用ctype构面确定什么是"空白",将其视为分隔符。使用将分隔符分类为空格的ctype构面,读取结果可能非常简单。这是实现方面的一种方法:
struct field_reader: std::ctype {
field_reader(): std::ctype(get_table()) {}
static std::ctype_base::mask const* get_table() {
static std::vector<:ctype_base::mask>
rc(table_size, std::ctype_base::mask());
// we'll assume dates are either a/b/c or a-b-c:
rc['/'] = std::ctype_base::space;
rc['-'] = std::ctype_base::space;
return &rc[0];
}
};
我们通过使用imbue告诉流使用包含它的语言环境,然后从该流中读取数据来使用它:
std::istringstream in("07/3/2011");
in.imbue(std::locale(std::locale(), new field_reader);
设置好后,拆分几乎变得微不足道-只需使用几个istream_iterator初始化向量以从字符串(嵌入在istringstream中)读取片段即可:
std::vector<:string>((std::istream_iterator<:string>(in),
std::istream_iterator<:string>());
显然,如果只在一个地方使用它,则可能会导致过度杀伤。但是,如果您使用过多,则在保持其余代码的整洁度方面可能要走很长的路要走。
我天生不喜欢stringstream,尽管我不确定为什么。今天,我编写了此函数,以允许将std::string通过任意字符或字符串拆分为向量。我知道这个问题很旧,但是我想分享一种拆分std::string的替代方法。
尽管可以很容易地修改它以包括它们,但是该代码完全省略了从结果中分割出的字符串部分。
#include
#include
void split(std::string str, std::string splitBy, std::vector<:string>& tokens)
{
/* Store the original string in the array, so we can loop the rest
* of the algorithm. */
tokens.push_back(str);
// Store the split index in a 'size_t' (unsigned integer) type.
size_t splitAt;
// Store the size of what we're splicing out.
size_t splitLen = splitBy.size();
// Create a string for temporarily storing the fragment we're processing.
std::string frag;
// Loop infinitely - break is internal.
while(true)
{
/* Store the last string in the vector, which is the only logical
* candidate for processing. */
frag = tokens.back();
/* The index where the split is. */
splitAt = frag.find(splitBy);
// If we didn't find a new split point...
if(splitAt == string::npos)
{
// Break the loop and (implicitly) return.
break;
}
/* Put everything from the left side of the split where the string
* being processed used to be. */
tokens.back() = frag.substr(0, splitAt);
/* Push everything from the right side of the split to the next empty
* index in the vector. */
tokens.push_back(frag.substr(splitAt+splitLen, frag.size()-(splitAt+splitLen)));
}
}
要使用,只需像这样致电...
std::string foo ="This is some string I want to split by spaces.";
std::vector<:string> results;
split(foo,"", results);
现在,您可以随意访问向量中的所有结果。就这么简单-没有stringstream,没有第三方库,没有回到C!
您对为什么会更好会有任何争议?
看看boost :: tokenizer
如果您想汇总自己的方法,则可以使用std::string::find()确定拆分点。
感谢您的字符串查找提示。永远喜欢听到std解决方案!
erase()函数呢?如果您知道要在字符串中拆分的位置,则可以使用erase()"提取"字符串中的字段。
std::string date("01/02/2019");
std::string day(date);
std::string month(date);
std::string year(date);
day.erase(2, string::npos); //"01"
month.erase(0, 3).erase(2); //"02"
year.erase(0,6); //"2019"
您是否有理由不想将string转换为字符数组(char*)?调用.c_str()相当容易。您还可以使用循环和.find()函数。
弦类
字符串.find()
字符串.c_str()
c语言字符串定界符,关于c ++:按字符分割字符串相关推荐
- vue把字符串分割成等长的若干字符串,根据特定字符分割字符串
一.把字符串分割成等长的若干字符串 1. 把字符串分割成特定长度的若干字符串(数组形式),这里举一个每5个字符为一组的例子 const strArr = 'new计算-架构&编程-语言'.ma ...
- SQL分割字符串,SQL按照指定字符分割字符串,SQL处理字符串...
SQL分割字符串,SQL按照指定字符分割字符串,SQL处理字符串 -----原文来源于网络 T-SQL对字符串的处理能力比较弱,比如我要循环遍历象1,2,3,4,5这样的字符串,如果用数组的话,遍历 ...
- 练习2-4:重新编写函数squeeze(s1,s2),将字符串s1中的任何字符与字符串时s2中的字符匹配的字符都删除
#include <stdio.h> void squeeze(char s1[], char s2[]); int main(){/*练习2-4:重新编写函数squeeze(s1,s2) ...
- C/C++根据特定字符分割字符串、读取文件去掉逗号等特定字符、strtok()函数详解
字符串分割情况 读取文件时,C++识别的是空格和换行符,但有时候文件是以符号分割的,如逗号等 字符串本身含有特殊符号,如逗号,@等 strtok()函数 strtok()函数能够按照特定的字符分解字符 ...
- 字符串在Java中_字符和字符串在Java中的旅程
以下是个人对java中字符和字符串的见解,如有疏漏之处,还请不吝赐教. 下面通过一个简单的程序来说明字符和字符串在Java中的旅程. 以字符 ' 中 '为例, 它的GBK编码是2个字节:0xd6d0, ...
- c语言 字符串切片重组成完整,完美分割字符串,实现字符串的splict功能
class Str:Client_C { string val; string[] str = new string[100]; public void StrT1() { //1.正常情况 //2. ...
- C语言函数 snprintf()(发送有限字符截断字符串输出到 str 所指向的字符串)(字符串拼接、截断拼接)
相似函数: C语言sprintf函数(发送格式化输出到 str 所指向的字符串)(format 标签属性)(字符串拼接) 文章目录 描述 声明 参数 返回值 实例 C 标准库 - <stdio. ...
- c语言判断全角和半角字符,对于字符串中全角字符和半角字符的判断
先拿空格来说: public class Test { private String regex = "^[//u0020//u3000]*$"; public boolean ...
- perl 字符串删除末尾几个字符_Perl字符串处理函数大全
本文重点讨论Perl字符串处理函数的用法,每种函数都有各自的特点和作用, 下面请看本文详细介绍. Perl字符串处理函数 1. index 语法: position=index(string,subs ...
最新文章
- 解决redis启动时的警告
- 详解:从Greenplum、Hadoop到现在的阿里大数据技术
- 教你玩转CSS Position(定位)
- 数组小案例(求数组最大最小值、反转数组中元素、指定元素第一次出现的索引)
- 线性回归—梯度下降python实现
- 用 Go 重构 C 语言系统,这个抗住春晚红包的百度转发引擎承接了万亿流量
- 接口自动化测试框架搭建(6、对接口进行mock的方法封装)--python+HTMLTestRunnerCN+request+unittest+mock+db
- tomcat下部署activemq(转)
- 现代操作系统的基本特性(2)
- 绝对靠谱安全的论文免费安全查重检测重复率网站
- 个人电脑组策略应用全攻略
- 菜菜的sklearn机器学习实战——全部课件
- 【科普】一读就懂:CPU到底是怎么识别代码的?
- 分布式WLAN全双工链路加权调度算法
- 计算机考证一级一般多少钱
- 两年多的社招经验分享,我的跳槽经验总结(含阿里滴滴美团快手头条)
- C语言show用法,show的用法和短语例句
- 12306登录password参数加密逻辑
- 二元函数对xy同时求导_关于反三角函数及其导数
- Golang适合高并发场景的原理
热门文章
- 25 个精美的后台管理界面模板和布局
- python中import的作用_python使用import报错是什么原因
- python常用单词自由且开放_python常用英语单词词汇 unit7
- Spring Boot 日志的使用及logback.xml的使用
- JavaScript | 声明数组并使用数组索引分配元素的代码
- 本月初 本月末 java_本月内容作家(2018年8月)
- android inflate,Android 关于inflate
- 基于嵌入式linux的数码相框的设计,基于Linux NFS的Web数码相框设计
- 大年初一,磊哥给大家发大红包啦!
- 第 6-1 课:Spring 核心 + 面试题