C++ stl中是否有进行字符串转换但带有长度参数的函数?
假设您有一个字符串:C++ stl中是否有进行字符串转换但带有长度参数的函数?,c++,stl,C++,Stl,假设您有一个字符串: std::string s = "ABCD\t1234"; 我可以使用std::string::find获取“\t”字符的偏移量,但据我所知,没有具有以下签名的函数: int atoi_n(char *, int len); 我遗漏了什么strtok将\t替换为\0,我不想接触原始缓冲区。我发现很难相信没有采用长度参数的atoi、atof等实例,但我什么都找不到 有人知道我是否遗漏了什么吗?我知道boost有一些标记器,但我不想添加boost的依赖性 看看目前为止的评论
std::string s = "ABCD\t1234";
我可以使用std::string::find
获取“\t”字符的偏移量,但据我所知,没有具有以下签名的函数:
int atoi_n(char *, int len);
我遗漏了什么strtok
将\t
替换为\0
,我不想接触原始缓冲区。我发现很难相信没有采用长度参数的atoi
、atof
等实例,但我什么都找不到
有人知道我是否遗漏了什么吗?我知道boost有一些标记器,但我不想添加boost的依赖性
看看目前为止的评论,我想澄清一下。让我们改变情景:
字符缓冲区[1024];
char*pStartPos;
char*pEndPost;
pStartPos=缓冲区+5;
pEndPos=缓冲器+10
也就是说,您不能对pStartPos和pEndPos之外的内存进行任何假设。如何将pStartPos和pEndPos之间的字符转换为int,而无需向缓冲区添加“\0”或使用substr进行复制?如果只想解析字符串的结尾(从
\t
之后的字符到结尾),只需将指针传递到要解析的第一个字符atoi
int n = atoi(s.c_str()+s.find('\t')+1);
(为了简洁起见,省略了错误检查-特别是,我们总是假设实际存在\t
)
相反,如果您想从字符串的开头一直解析到\t
,您可以这样做
int n = atoi(s.c_str());
因为atoi
始终在第一个非数字字符处停止
顺便说一下,你应该考虑使用更健壮的解析数字的方法,如<代码> StrtoL>代码>代码> SCASNF 或C++流——它们都可以以某种方式报告解析错误,而<>代码> ATOI 只返回<代码> 0 (这与解析字符串的0不可区分)。
顺便说一句,
atoi
无论如何都不在“STL”中,它只是C标准库的一部分
我知道atoi不在STL中。我想知道STL中是否有类似的东西,可以指定转换中要包含的最后一个字符。基本上,我有一个缓冲区,它可能会被部分垃圾填满。我知道可能有效数据的开始和可能有效数据的结束。我不想依靠空格来结束转换,我想明确说明“field”的长度,因为它也可能不会以/0结尾 如果您确定垃圾不是以数字开头的,您可以使用
atoi
/strtol
/istringstream
原样-它们在看到垃圾时自动停止。否则,请使用substr
方法提取所需的确切子字符串:
std::string mayContainGarbage="alcak123456amaclmò";
std::string onlyTheDigits=mayContainGarbage.substr(5, 6);
// now parse onlyTheDigits as you prefer
如果只想解析字符串的结尾(从
\t
后面的字符到结尾),只需将指针传递到要解析的第一个字符atoi
int n = atoi(s.c_str()+s.find('\t')+1);
(为了简洁起见,省略了错误检查-特别是,我们总是假设实际存在\t
)
相反,如果您想从字符串的开头一直解析到\t
,您可以这样做
int n = atoi(s.c_str());
因为atoi
始终在第一个非数字字符处停止
顺便说一下,你应该考虑使用更健壮的解析数字的方法,如<代码> StrtoL>代码>代码> SCASNF 或C++流——它们都可以以某种方式报告解析错误,而<>代码> ATOI 只返回<代码> 0 (这与解析字符串的0不可区分)。
顺便说一句,
atoi
无论如何都不在“STL”中,它只是C标准库的一部分
我知道atoi不在STL中。我想知道STL中是否有类似的东西,可以指定转换中要包含的最后一个字符。基本上,我有一个缓冲区,它可能会被部分垃圾填满。我知道可能有效数据的开始和可能有效数据的结束。我不想依靠空格来结束转换,我想明确说明“field”的长度,因为它也可能不会以/0结尾 如果您确定垃圾不是以数字开头的,您可以使用
atoi
/strtol
/istringstream
原样-它们在看到垃圾时自动停止。否则,请使用substr
方法提取所需的确切子字符串:
std::string mayContainGarbage="alcak123456amaclmò";
std::string onlyTheDigits=mayContainGarbage.substr(5, 6);
// now parse onlyTheDigits as you prefer
据我所知,没有现成的功能,但它应该不难实现 例如:
template <typename ForwardIterator>
int range_to_int(ForwardIterator begin, ForwardIterator past_end) {
if (begin != past_end) {
bool negative = false;
auto ch = *begin;
if (ch == '-') {
negative = true;
++begin;
}
else if (ch == '+')
++begin;
if (begin != past_end) {
int result = 0;
do {
auto ch = *begin;
if (ch < '0' || ch > '9')
throw std::invalid_argument("Invalid digit.");
result = result * 10 + (ch - '0');
++begin;
} while (begin != past_end);
if (negative)
result = -result;
return result;
}
throw std::invalid_argument("+ or - must be followed by at least one digit.");
}
throw std::invalid_argument("Empty range.");
}
模板
int range_到_int(ForwardIterator begin,ForwardIterator Pass_end){
如果(开始!=结束){
布尔阴性=假;
自动ch=*开始;
如果(ch='-'){
负=真;
++开始;
}
else如果(ch=='+')
++开始;
如果(开始!=结束){
int结果=0;
做{
自动ch=*开始;
如果(ch<'0'| ch>'9')
抛出std::无效的_参数(“无效数字”);
结果=结果*10+(ch-“0”);
++开始;
}while(开始!=结束);
如果(否定)
结果=-结果;
返回结果;
}
throw std::无效的_参数(“+或-后面必须至少跟一位数字”);
}
抛出std::无效的_参数(“空范围”);
}
您可以这样使用它:
int main() {
const char* buffer = "abc-123def";
int i = range_to_int(buffer + 4, buffer + 7);
assert(i == 123);
i = range_to_int(buffer + 3, buffer + 7);
assert(i == -123);
try {
i = range_to_int(buffer + 3, buffer + 8);
assert(false);
}
catch (const std::exception& ex) {
std::cout << ex.what() << std::endl;
}
try {
i = range_to_int(buffer + 3, buffer + 4);
assert(false);
}
catch (const std::exception& ex) {
std::cout << ex.what() << std::endl;
}
try {
i = range_to_int(buffer + 4, buffer + 4);
assert(false);
}
catch (const std::exception& ex) {
std::cout << ex.what() << std::endl;
}
// You can use it on std::string as well....
const std::string str = buffer;
i = range_to_int(str.begin() + 4, str.begin() + 7);
assert(i == 123);
// Etc...
return EXIT_SUCCESS;
}
intmain(){
const char*buffer=“abc-123def”;
int i=范围_至_int(缓冲区+4,缓冲区+7);
断言(i==123);
i=范围_至_int(缓冲区+3,缓冲区+7);
断言(i==-123);
试一试{
i=范围_至_int(缓冲区+3,缓冲区+8);
断言(假);