【问题标题】:Why this code error when entering a 4*x symbol number or more? Converting a 16 digit number into 10 digit number为什么输入 4*x 或更多符号时出现此代码错误?将 16 位数字转换为 10 位数字
【发布时间】:2020-03-31 18:42:25
【问题描述】:

-程序将数字(16)的值作为char(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E的字符串,F)

-根据字符表转码为正确的值

-将数值转换为十进制


但是...如果:

在:A |出:10(+)

在:AA |输出:170(+)

在:AAA| out: ...忘记答案但是(+)

!!!在:AAAA|出:错误(-)

为什么?

#include <STDIO.H>
#include <CONIO.H>
void main()
{
    char m[100];                                // init massive chars [m] 
    gets(m);                                    // input massive [m] (16 digit number)
    int i = -1;                                 // init counter for [m] (-1 for start [i++] in 0 pos)

    while (m[i++]);                             // go to last postion in [m] and count length
    i--;                                        // step back for skip '\0'
    i--;                                        // step back for start position last char
    int s = 0;                                  // init sum  number (10 digit number)
    int v = 1;                                  // init multiplier

    while (i >= 0)                              // it is first char?
    {
        if ((m[i] >= 'A') && (m[i] <= 'F')) s += ((int)(m[i]-55) * v); // if char 'A'(65) char = (10)  * multiplier
        else s += ((int)(m[i]) * v);                                // else char 1,2,3,4,5... (1,2,)* multiplier
        v *= 16;                                // up multiplier power
        i--;                                    // char step back
    }
    printf("%i", s);                            //out sum
}

在 cmets 之后编辑:

char m[100];
gets(m);
int i = 0;       // * "=-1" -> "0"
while (m[++i]);  // * "i++" -> "++i"
i--;

double s = 0; int v = 1;
while (i >= 0)
{
  if ((m[i] >= 'A') && (m[i] <= 'F'))  s += ((int)(m[i]-55) * v);
  if ((m[i] >= '0') && (m[i] <= '9'))  s += ((int)(m[i]-48) * v); //add this rules

  v *= 16;
  i--;
}

printf("%lf", s);

+带有输出结果的图像 1 & 2

在 cmets 之后编辑:

char m[100];
gets(m);
for (int i = 0; m[i] != '\0'; i += 1); // * 

unsigned long int s = 0; unsigned long int v = 1;    // *
for (int u = 0; u < i; u += 1)
{
  if ((m[u] >= 'A') && (m[u] <= 'F'))  s += ((int)(m[u]-55) * v); 
  if ((m[u] >= '0') && (m[u] <= '9'))  s += ((int)(m[u]-48) * v);

  v *= 16;
}

printf("%lu", s);                      // *

【问题讨论】:

  • 听起来您可能需要学习如何使用调试器来单步调试您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programsDebugging Guide
  • while (m[i++]);未定义的行为,因为第一次迭代尝试访问m[-1]。顺便说一句,您似乎正在使用一个非常旧的编译器,您可以轻松更新。有适用于 Linux 和 Windows 的免费编译器......而且你似乎在第 17 行缺少if
  • 由于i-1 开头,您应该将while (m[i++]); 替换为while (m[++i]);。换句话说,pre-increment i 而不是 post-incrementing。然后您可以删除它后面的i--; 语句之一。 i 将是while 循环后空终止符的位置,因此您只需后退一位即可。
  • 试图将开始状态更改为零...
  • 试图改变“未定义的行为”...

标签: c terminal console numbers


【解决方案1】:

我应该从 0 开始,而不是 -1。

您还没有注意到,但您的数学运算对于数字 0 到 9 是错误的。

如果您希望 16 个十六进制字符的所有输出都是正数,您需要一个无符号的 64 位整数(但是这在您的平台/编译器上实现)并且您需要打印无符号长整数(即不是 %i/%d)。

【讨论】:

  • 虽然 double 是正确的大小,但我怀疑你想要小数。您要查找的变量类型是long unsigned int。要打印它 printf 将寻找 "%lu
  • 快到了。 int v 也变得非常大,unsigned long int v 然后它在这里工作。
猜你喜欢
  • 2020-07-19
  • 2013-05-07
  • 2013-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-09
  • 2021-07-15
  • 1970-01-01
相关资源
最近更新 更多