我正在尝试编写一个程序,该程序接受-十六进制,八进制和十进制-的输入,将它们存储在整数变量中,并输出它们以及将其转换为十进制形式。 例如:

用户输入:0x43、0123、65

程序输出:

0x43 hexadecimal converts to 67 decimal
0123 octal converts to 83 decimal
65 decimal converts to 65 decimal

所以显然我需要一种解释数字的方法,但是我不确定如何去做。 我尝试了各种方法,例如将它们读入函数并将其转换为字符串,反之亦然(请参见此处的代码示例),但是解释数字始终需要转换为某种破坏原始输入的格式。

我唯一想到的是重载>>运算符,该运算符一次读取一个字符,如果在输入的开头看到0x或0,则它将整个输入存储到字符串中,然后再将其读入int。 然后,程序将以某种方式必须在输出期间确定正确的操纵器。

不知道是否有更简单的方法来执行此操作,我们将为您提供帮助。

编辑:这已经解决,但是我决定在任何人感兴趣的情况下发布代码。

#include "std_lib_facilities.h"

void number_sys(string num, string& s)
{
  if(num[0] == '0' && (num[1] != 'x' && num[1] != 'X')) s = "octal";
  else if(num[0] == '0' && (num[1] == 'x' || num[1] == 'X')) s = "hexadecimal";
  else s = "decimal";
}

int main()
{
    cout << "Input numbers in hex, dec, or oct. Use 0xx to cancel.\n";
    string a;

    while(cin >> a){
    if(a == "0xx")break;
    string atype;
    number_sys(a, atype);

    int anum = strtol(a.c_str(), NULL, 0);

    cout << a << setw(20-a.length()) << atype << setw(20) << "converts to" << setw(10)
         << anum << setw(10) << "decimal\n";
                 }

    keep_window_open();
}

===============>>#1 票数:11 已采纳

看一下strtol函数。

char * args[3] = {"0x43", "0123", "65"};
for (int i = 0; i < 3; ++i) {
  long int value = strtol(args[i], NULL, 0);
  printf("%s converts to %d decimal\n", args[i], value);
}

输出:

0x43 converts to 67 decimal
0123 converts to 83 decimal
65 converts to 65 decimal

===============>>#2 票数:1

您总是可以将其存储为字符串以开始,然后查看前两个字符以查看它们是否为0x:

std::string num;
std::cin >> num;

if (num[0] == '0' && num[1] == 'x')
{ 
  //handle
}

===============>>#3 票数:1

我不确定是否有C ++的方法来执行此操作,但是如果您不介意一点C-ishness,可以将其读入char数组并使用sscanf(buffer, "%i", &output) 就像您所描述的那样, %i根据其格式将输入解释为十六进制,八进制或十进制。

编辑:啊,不知道strtol也可以做到这一点。 不理我。

===============>>#4 票数:1

如果要保留基本信息(十六进制/八进制/十进制),则需要将该信息与整数值本身分开存储,这将要求您至少解析输入字符串的前几个字符(sscanf (),strtol()等不会为您保留该信息)。

您可以滚动自己的微型解析器,以保存输入库并进行转换(代码未经测试就被搁置了):

char inputStr[MAX_INPUT_LENGTH+1];
char *p;
int result = 0;
char values[128];

/**
 * This enumeration serves double duty; it keeps track of what
 * base the input was entered in, and it controls the state machine 
 * used to parse the input; from a didactic POV, this is probably bad form
 */
enum {
  eStart, 
  eHexOrOctal, 
  eOctal, 
  eDecimal, 
  eHexadecimal, 
  eError
} eBase = eStart;


/**
 * Use the values array as a table to map character constants to their corresponding 
 * integer values.  This is safer than using an expression like *p - '0', in 
 * that it can work with character encodings where digits are not consecutive.
 * Yes, this wastes a little space, but the convenience makes
 * up for it IMO.  There are probably better ways to do this.
 */
values['0'] = 0; values['1'] = 1; values['2'] = 2; values['3'] = 3; 
values['4'] = 4; values['5'] = 5; values['6'] = 6; values['7'] = 7; 
values['8'] = 8; values['9'] = 9; values['a'] = 10; values['b'] = 11; 
values['c'] = 12; values['d'] = 13; values['e'] = 14; values['f'] = 15;

/**  
 * Insert code to get input string here 
 */

for (p = inputStr; *p != 0; p++)
{
  /**
   * Cycle through each character in the input string, adjusting the state
   * of the parser as necessary.  Parser starts in the eStart state.
   */
  switch(eBase)
  {
    /**
     * Start state -- we haven't parsed any characters yet
     */
    case eStart:
      if (*p == '0') eBase = eHexOrOctal; // leading 0 means either hex or octal
      else if (isdigit(*p))
      {
        eBase = eDecimal;    // leading non-0 digit means decimal
        result = values[*p];  
      }                    
      else eBase = eError;    // no other character may start an integer constant
      break;
    /**
     * HexOrOctal -- we've read a leading 0, which could start either a hex or
     * octal constant; we need to read the second character to make a determination
     */
    case eHexOrOctal:      
      if (tolower(*p) == 'x')  base = eHexadecimal;
      else if (isdigit(*p) && *p != '8' && *p != '9')
      {
        base = eOctal;   
        result = values[*p];
      }
      else eBase = eError;
      break;
    /**
     * Octal -- we are parsing an octal constant
     */
    case eOctal:
      if (isdigit(*p) && *p != '8' && *p != '9')
      {
        result *= 8;
        result += values[*p];
      }
      else eBase = eError;
      break;
    /**
     * Decimal -- we are parsing a decimal constant
     */
    case eDecimal:
      if (isdigit(*p))
      {
        result *= 10;
        result += values[*p];
      }
      else eBase = eError;
      break;
    /**
     * Hexadecimal -- we are parsing a hex constant
     */
    case eHexadecimal:
      if (isxdigit(*p))
      {
        result *= 16;
        result += values[tolower(*p)];
      }
      else eBase = eError;
      break;
    /**
     * String is not a properly formatted integer constant in 
     * any base; once we fall into the error state, we stay there.
     */
    case eError:
    default:
      break;
  }
}
if (eBase != eError)
{
  printf("input: %s ", inputStr); fflush(stdout);
  switch(eBase)
  {
    case eOctal: printf("octal "); break;
    case eHexadecimal: printf("hexadecimal "); break
    default: break;
  }
  fflush(stdout);
  printf("converts to %d decimal\n", result);
}
else
{
  /** Print a suitable error message here */
}

===============>>#5 票数:0

如果从字面上看必须使用单个整数变量来存储显示最终输出所需的所有信息,则必须使用整数变量的一部分来存储输入所在的原始基数。否则无法恢复。

  ask by trikker translate from so

未解决问题?本站智能推荐:

3回复

C ++,将输入字符串转换为数字,转换失败不应返回零

这个问题已经在这里有了答案: 在C ++(gcc)中是否有等效的TryParse? 4个答案 大家好,我来看看c ++ strtol , strtoll , strtoul , atol等中的字符串转换方法。似乎每个字符串中的每个都会返回0 (或0.0 ),这是导
1回复

十六进制到十进制

我必须将十六进制数转换为十进制数,但不知道如何。 在AutoIt文档中(如下图所示)定义了一些常量(被指定为十六进制值): 0x00200000十六进制(图像中带下划线)等于8192十进制(这是真正的转换)。 但转换器返回2097152 。 我必须转换另一个十六进制值( 0x000
2回复

十六进制到十进制转换

我必须将十六进制转换为十进制值,然后将其乘以10,然后再转换回十进制。 我弄清楚了大部分问题,当我将其乘以10并将其转换回十六进制值时,就会发生问题。 我知道有一种更简单的方法,只需使用char数组即可完成。 我似乎无法弄清楚哪里出了问题。
1回复

根据前缀将整数字符串解析为十进制,八进制或十六进制

我想解析一个包含以十进制,八进制或十六进制格式的数字的字符串,并且我想使用零堆分配做到这一点。 因此,正则表达式和子字符串不存在。 基数通过前缀确定: 十进制1234 01234是八进制的,因为前导零(668十进制) 0x1234为十六进制,原因是前导0x (十
1回复

将十六进制数字转换为十进制以进行比较(C)

我正在尝试创建一个程序,该程序确定是否正确创建了一个int十六进制文件,而我用来生成它们的一个程序却无法正确生成一个文件,因此我要制作一个。 到目前为止,我可以从目标文件中读取一行,但是将十六进制数从字符串转换为要比较的数字时遇到问题。 这是我令人烦恼的片段: 这些sprintf
1回复

VB.net检测数字是十进制还是十六进制

我有一个VB.NET应用程序,我需要检查在字符串中输入的数字是否为十六进制或十进制格式 例如,看这里: 这是用十进制格式(第一个)和十六进制格式(第二个)写的相同数字。 如何编写自动检测案件的功能? 谢谢
3回复

将大十六进制转换为十进制数字

我有一个大的十六进制数字,例如CD4A0619FB0907BC00000 (25!)或任何其他类似的数字。 现在,仅使用标准C / C ++代码(没有像Boost那样的库),我想将此数字转换为十进制数字15511210043330985984000000。不幸的是,它对于64位整数(如long
1回复

无法正确将十六进制转换为十进制

我在理解十六进制字节时遇到麻烦。 当手册中以十六进制表示的Header ID为7Fh时,则表示0111 1111对吗? 根据在线十六进制十进制转换器,它将转换为十进制127。 我看到的输出是 我在这里做错了什么?
2回复

如何将负十六进制转换为十进制

嗨,我想知道如何将十六进制负值(到补码编码)转换为十进制,很容易,不用将十六进制转换为二进制,然后将每个位乘以2的幂,并将所有值相加得到结果,它需要太多时间:数字(32位)的例子:0xFFFFFE58 那怎么办呢?
15回复

确定String是否为数字并使用Java进行转换?

我知道之前经常会问过这个问题的变体(例如这里和这里 ),但这并不是那些完全重复的。 我想检查String是否是一个数字,如果是,我想将它存储为double 。 有几种方法可以做到这一点,但所有这些方法似乎都不适合我的目的。 一种解决方案是使用Double.parseDouble(s