C++ 使用string.substr(post,len)的无限循环

C++ 使用string.substr(post,len)的无限循环,c++,string,while-loop,C++,String,While Loop,你能找出为什么它在控制台中无限循环吗?程序员应该列出用户插入字符串的每个字符,在每个唯一字符旁边的括号中,应该显示该字符在字符串中出现的次数。。。不知道为什么 #包括 #包括 #包括 使用名称空间std; int main(){ 字符串输入; cout>输入; 排序(input.begin(),input.end()); 而(!input.empty()){ int j{1},i{0}; while(input.at(i)=input.at(i+1)){ j++; i++; } 这句话怎么说 i

你能找出为什么它在控制台中无限循环吗?程序员应该列出用户插入字符串的每个字符,在每个唯一字符旁边的括号中,应该显示该字符在字符串中出现的次数。。。不知道为什么

#包括
#包括
#包括
使用名称空间std;
int main(){
字符串输入;
cout>输入;
排序(input.begin(),input.end());
而(!input.empty()){
int j{1},i{0};
while(input.at(i)=input.at(i+1)){
j++;
i++;
}
这句话怎么说

input.substr(i);
不更改对象
输入
本身

因此,如果对于某些索引
i
input.at(i)
不等于
input.at(i+1)
,您将有一个无限循环,或者您可以有一个超出范围的异常,因为
i+1
可以等于
input.size()

抛出:如果pos>=size(),则抛出\u超出\u范围

这个程序可以用不同的方法来实现。例如下面的方法

#include <iostream>
#include <string>
#include <algorithm>

int main() 
{
    std::cout << "input string: ";
    std::string input;
      
    std::cin >> input;
      
    std::sort( input.begin() , input.end() );
    
    for ( size_t i = 0; i < input.size(); )
    {
        size_t j = input.find_first_not_of( input[i], i );
        
        if ( j == std::string::npos ) j = i + 1;
        
        if ( i != 0 ) std::cout << ", ";
        std::cout << input[i] << " (" << j - i << ")";

        i = j;
    }
    
    std::cout << '\n';
    
    return 0;
}
或者您可以使用标准容器
std::map
std::unordered\u map
,例如

#include <iostream>
#include <string>
#include <map>

int main() 
{
    std::cout << "input string: ";
    std::string input;
      
    std::cin >> input;
      
    std::map<char, size_t> m;
    
    for ( const auto &c : input )
    {
        ++m[c];
    }

    bool first = true;
    for ( const auto &p : m )
    {
        if ( !first  ) std::cout << ", ";
        std::cout << p.first << " (" << p.second << ")";
        first = false;
    }
    
    std::cout << '\n';
    
    return 0;
}

哦,哇,它应该是
string=string.substr(post,len)
谢谢,它现在抛出了一个std::超出范围的错误…好了,我现在知道了,thanks@Biaaach
string::at()
执行边界检查,如果给定的索引超出边界,将引发异常。
input.at(i+1)当
i
到达
input
@RemyLebeau的最后一个字符时,
将超出范围,但如果不使用尾部递归,如何解决这个问题呢?没有未定义的行为,因为
input。at(i+1)
将引发异常。您可能正在考虑
string::operator[]
相反,它在C++11之前确实会有未定义的越界索引行为。但是自从C++11以后,
操作符[]
允许
索引==size()
,但
字符串::at()允许
nots.argh,那么我把这一切都想错了……一定是一种更好的编写代码的方法。@VladfromMoscow这很有说服力,谢谢bunch@VladfromMoscow您使用size\u t而不是unsigned int有什么特别的原因吗?@biaach感谢您的建议。
#include <iostream>
#include <string>
#include <map>

int main() 
{
    std::cout << "input string: ";
    std::string input;
      
    std::cin >> input;
      
    std::map<char, size_t> m;
    
    for ( const auto &c : input )
    {
        ++m[c];
    }

    bool first = true;
    for ( const auto &p : m )
    {
        if ( !first  ) std::cout << ", ";
        std::cout << p.first << " (" << p.second << ")";
        first = false;
    }
    
    std::cout << '\n';
    
    return 0;
}
#include <iostream>
#include <string>
#include <map>

int main() 
{
    std::cout << "input string: ";
    std::string input;
      
    std::cin >> input;
      
    auto less = [&input]( const auto &c1, const auto &c2 )
    {
        return input.find( c1 ) < input.find( c2 );
    };
    
    std::map<char, size_t, decltype( less )> m( less );
    
    for ( const auto &c : input )
    {
        ++m[c];
    }
    
    bool first = true;
    
    for ( const auto &p : m  )
    {
        if ( !first  ) std::cout << ", ";
        std::cout << p.first << " (" << p.second << ")";
        first = false;
    }
    
    std::cout << '\n';
    
    return 0;
}
#include <iostream>
#include <string>

int main() 
{
    std::cout << "input string: ";
    std::string input;
      
    std::cin >> input;
      
    for ( size_t i = 0; i < input.size(); i++ )
    {
        size_t j = 0;
        
        while ( j != i && input[j] != input[i] ) j++;
        
        if ( j == i )
        {
            size_t count = 1;
            while ( ++j < input.size() )
            {
                if ( input[j] == input[i]  ) ++count;
            }
            if ( i != 0  ) std::cout << ", ";
            std::cout << input[i] << " (" << count << ")";
        }
    }
    
    std::cout << '\n';
    
    return 0;
}
input string: elephant
e (2), l (1), p (1), h (1), a (1), n (1), t (1)