Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何实现自己的字符串到整数的转换_C++_String_Function - Fatal编程技术网

C++ 如何实现自己的字符串到整数的转换

C++ 如何实现自己的字符串到整数的转换,c++,string,function,C++,String,Function,因此,我想通过创建自己的函数,而不是使用stoi/atoi函数,将8302之类的字符串转换为整数 到目前为止,我通过以下方式进行了尝试: int stringToInt(string input) { int i = 0; while(input[i] >= '0' && input[i] <= '9') { input[i] = input[i] * 10 + ...... i++; } return

因此,我想通过创建自己的函数,而不是使用stoi/atoi函数,将8302之类的字符串转换为整数

到目前为止,我通过以下方式进行了尝试:

int stringToInt(string input)
{
    int i = 0;
    while(input[i] >= '0' && input[i] <= '9')
    {
        input[i] = input[i] * 10 + ......
        i++;
    }
return i;
}
int stringToInt(字符串输入)
{
int i=0;
while(输入[i]>='0'&&input[i]
void强制执行(bool b){
如果(!b){
抛出std::range_错误(“不是要转换为整数的有效字符串”);
}
}
int stringToInt(标准::字符串){
对于(std::size_t i(0);i!=(最后一个);+i){

强制(('0'最好从右向左开始转换

因此,您将迭代字符串,从它的结尾开始,到它的开头结束。在每次迭代中,我们将获取字符,将其转换为int,并将其与它的
乘数相乘(它在结果整数中的位置),然后将其添加到最终结果中

这应该起作用:

#include <iostream>
#include <string>

int stringToInt(std::string input)
{
    int result = 0;
    int multiplier = 1;

    for (int i = input.length() - 1; i >= 0; i--) // start from right
    {
        if (input[i] - '0' < 0 || input[i] - '0' > 9) // if any character is not an integer, return maximum negative
        {
            result = INT16_MIN;
            break;
        }

        result += (input[i] - '0') * multiplier; // convert to int, get its position and then add it to result.
        multiplier *= 10; // get next position
    }

    return result;
}

int main()
{
    std::string MyEx = "123456";
    int MyInt = stringToInt(MyEx);

    std::cout << MyInt;

    return 0;
}
#包括
#包括
int stringToInt(标准::字符串输入)
{
int结果=0;
整数乘数=1;
for(int i=input.length()-1;i>=0;i--)//从右开始
{
if(输入[i]-'0'<0 | |输入[i]-'0'>9)//如果任何字符不是整数,则返回最大负数
{
结果=INT16_MIN;
打破
}
结果+=(输入[i]-“0')*乘法器;//转换为int,获取其位置,然后将其添加到结果中。
乘数*=10;//获取下一个位置
}
返回结果;
}
int main()
{
std::string MyEx=“123456”;
int MyInt=stringToInt(MyEx);

std::cout以递归的方式进行可能是最容易的。使用以下想法:

8302 = 830 * 10 + 2
即:

  • 如果字符串中只有一个
    char
    ,则返回它;否则继续
  • 分隔字符串中的最后一个
    char
  • 使用递归将字符串(不带最后一个字符)转换为整数
  • 乘以10并将最后一个
    char
  • 这里有很多细节:

    • 如何将1
      char
      转换为整数?-从中减去
      '0'
    • 如何将
      字符
      与字符串的其余部分分开?-使用
    • 当您有一个可工作的递归解决方案时,您可能希望将其转换为一个迭代解决方案-这将使其更快,但可读性可能更低
    • 如何处理无效字符串,如
      “aaa”
      “123haha”
      -我的算法无法处理该问题

    这一次非常接近您的尝试:

    int toInt(const std::string& input)
    {
      int i = 0;
      for (const auto c : input)
      {
        if (c < '0' || c > '9')
          break;
        i = i*10 + c-'0';
      }
      return i;
    }
    
    int-toInt(常量std::字符串和输入)
    {
    int i=0;
    用于(常数自动c:输入)
    {
    如果(c<'0'| c>'9')
    打破
    i=i*10+c-'0';
    }
    返回i;
    }
    
    唯一的假设是
    '0'
    '9'
    的字符在字符集中彼此紧挨着。
    if
    语句确保我们在非数字字符处停止。数字字符使用
    c-'0'
    转换为其整数值


    请记住,这只解析字符串的第一个数字。以符号
    +
    -
    开头的字符串不被考虑。

    一个好方法是找到你的第一个数字,然后从那里开始创建一个多人游戏变量,并将其乘以每一个数字的10。对于你添加的每个字符,你必须从中减去“0”作为“0”不等于int 0

    例如:

     string s = "12346";
     int multiplayer = 1;
     int i = 0;
    
     int result = 0;
    
     while (s[i] >= '0' && s[i] <= '9')
     ++i;
    
    --i;
    for(i ; i >= 0 ; --i){
       result += (s[i] - '0') * multiplayer;
       multiplayer *= 10;
     }
    
    string s=“12346”;
    int多人游戏=1;
    int i=0;
    int结果=0;
    而(s[i]>='0'和&s[i]=0;--i){
    结果+=(s[i]-“0')*多人游戏;
    多人游戏*=10;
    }
    
    在定义字符转换之前:

    inline int ctoi(char c) {
      switch (c) {
        case '0':
          return 0;
        case '1':
          return 1;
        case '2':
          return 2;
        case '3':
          return 3;
        case '4':
          return 4;
        case '5':
          return 5;
        case '6':
          return 6;
        case '7':
          return 7;
        case '8':
          return 8;
        case '9':
          return 9;
        default:
          throw std::runtime_error("Invalid char conversion");
      }
    }
    
    并使用它:

    int my_stoi_dec(const std::string& str) {
      int rtn = 0;
      int exp = 1;
      for (auto cp = str.crbegin(); cp != str.crend(); ++cp) {
        char c = *cp;
        if (isdigit(c)) {
          rtn +=  ctoi(c) * exp;
          exp *= 10;
        } else if (c == '+') {
          return rtn;
        } else if (c == '-') {
          return rtn * -1;
        } else {
          throw std::runtime_error("Integer error conversion");
        }
      }
    }
    

    为什么要将字符串中的每个ASCII字符值乘以10?不应该对字符串索引和累加器使用同一个变量。对累加器使用单独的变量。并且返回的是索引,而不是转换后的数字。此外,不检查字符串的结尾。@FirstStep这是一个c++17功能,称为awesomelipsis。可变模板的扩展,它会自动为您完成整个程序。只需粘贴到堆栈溢出中即可。@第一步请参见?6个答案:)从操作代码和检查中,您无法确保所有字符串项都是正确的digits@HumamHelfawiOP没有说明这一点。根据他的示例输入,不清楚其中一个字符是否不是整数。我还是添加了它,感谢您指出。
    10^I
    并没有做您认为它会做的事情。OP应该考虑的其他几点:a.处理负数。b.如果第4步会使累加器溢出,该怎么办(还有一些有趣的问题,关于如何在不触发溢出的情况下检测到)c.将后两种方法结合起来:在不触发溢出的情况下处理最负数的输入。我认为这些注意事项主要是为将来可能阅读本文的其他人考虑的;OP提到了“stoi/atoi”所以他似乎不关心这些事情,就像这是最干净的一样。你应该在你的答案上加上解释,因为它似乎最适合按原样使用。你不应该使用神奇的数字。这使得代码不可移植。@NathanOliver更好?是的。这是迄今为止最完整的答案。它不能在任何情况下处理/但我不会投反对票。
    int my_stoi_dec(const std::string& str) {
      int rtn = 0;
      int exp = 1;
      for (auto cp = str.crbegin(); cp != str.crend(); ++cp) {
        char c = *cp;
        if (isdigit(c)) {
          rtn +=  ctoi(c) * exp;
          exp *= 10;
        } else if (c == '+') {
          return rtn;
        } else if (c == '-') {
          return rtn * -1;
        } else {
          throw std::runtime_error("Integer error conversion");
        }
      }
    }