【问题标题】:A cleaner way to convert a string to int after checking for hex prefix?检查十六进制前缀后将字符串转换为 int 的更简洁方法?
【发布时间】:2013-12-17 16:31:40
【问题描述】:

这个小练习旨在从用户那里获取一个字符串,该字符串可以是十进制、十六进制或八进制。首先,我需要确定字符串是哪种数字。第二,我需要将该数字转换为 int 并以正确的格式显示该数字,例如:

cout <<(dec,hex,oct, etc)<< number;

这就是我想出的。我想要一种更简单、更干净的方式来写这个。

string number = "";
cin >> number;
string prefix = "dec";
char zero = '0';
char hex_prefix = 'x';
string temp = "";
int value = 0;

for(int i =0; i<number.size();++i)
{
    if(number[0] == zero)//must be octal or hex
    {
        if (number[0] == zero && number[1] == hex_prefix ) //is hex
        {
            prefix = "hex";
            for(int i = 0; i < (number.size() - 2); ++i)
            {
                temp[i] = number[i+2]; 

            }
            value = atoi(temp.c_str()); 
        }
        //... code continues to deal with octal and decimal

【问题讨论】:

  • 我没有看到第一个 for 循环的必要性。
  • 我建议发布输入字符串的样子,以便我们为您提供更好的答案。

标签: c++ iostream base


【解决方案1】:

您检查了两次number[0],这是第一个最明显的问题。

内部的if 已经检查了number[0]number[1],我看不出外部的意义。

最外层的循环也很难理解,你希望数字之前不是十六进制数据,还是什么?关于预期输入字符串的外观,您的问题可能会更清楚。

我认为最干净的方法是忽略这一点,并将其推送到可以解析任何基数的整数的现有(库)代码中。在 C 语言中我会推荐 strtoul(),当然你也可以在 C++ 中使用它。

【讨论】:

  • 根据需要使用strtol()strtoul() 会为您检查是否将base 参数指定为零。
【解决方案2】:

您有两个具有相同值整数的内部循环,这可能是您的代码中的冲突问题。我建议您查看 c++ 库中的 isdigitislower 方法,并利用这些方法来完成您的任务。 isdigit & islower

祝你好运

【讨论】:

    【解决方案3】:

    这是打印删除十六进制前缀后的数字,否则返回0:

    #include<iostream>
    #include<cmath>
    #include<stdlib.h>
    using namespace std;
    int main(){
            string number = "";
            cin >> number;
            string prefix = "dec";
            char zero = '0';
            char hex_prefix = 'x';
            string temp = "";
            int value = 0;
            if (number.size()>=2 && number[0] == zero && number[1] == hex_prefix ) //is hex
            {
                prefix = "hex";
                for(int i = 0; i < (number.size() - 2); ++i)
                {
                    temp[i] = number[i+2];
    
                }
    
                value = atoi(temp.c_str());
             }
             cout<<value;
            return 0;
    }
    

    【讨论】:

      【解决方案4】:

      我找到的这个部分解决方案尽可能干净,但它没有报告整数的格式:

      int string_to_int(std::string str)
      {
          std::istringstream stream;
          stream.unsetf(std::ios_base::dec);
          int result;
          if (stream >> result)
              return result;
          else
              throw std::runtime_error("blah");
      }
      
      ...
      
      cout << string_to_int("55") << '\n';   // prints 55
      cout << string_to_int("0x37") << '\n'; // prints 55
      

      这里的重点是stream.unsetf(std::ios_base::dec) - 它取消了默认设置的“十进制”标志。此格式标志告诉 iostreams 期待一个十进制整数。如果未设置,iostreams 期望任何基数的整数。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-07
        • 2020-07-18
        • 1970-01-01
        • 2016-03-15
        相关资源
        最近更新 更多