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);
断言(假);