【问题标题】:How to handle negative integer when converting them to strings? [closed]将它们转换为字符串时如何处理负整数? [关闭]
【发布时间】:2018-08-16 07:48:34
【问题描述】:

我需要将整数转换为字符串,无论是负数还是正数。 到目前为止,我能够使用以下代码将正整数转换为字符串。 但不是负面的。我怎样才能正确处理它们以将它们转换为字符串。 这是我使用的代码。

谢谢

拉贾特!

 /*
  * C Program which Converts an Integer to String & vice-versa
*/

#include <stdio.h>
#include <string.h>
#include <math.h>

void tostring(char [], int);


int main()
{
char str[10];
int num, result;

printf("Enter a number: ");
scanf("%d", &num);
tostring(str, num);
printf("Number converted to string: %s\n", str);


return 0;
}

void tostring(char str[], int num)
  {
    int i, rem, len = 0, n;

if(num<0)
{
    n=(-1)*(num);

}
else
{
    n=num;
}
while (n != 0)
{
    len++;
    n /= 10;
}
for (i = 0; i < len; i++)
{
    rem = num % 10;
    num = num / 10;
    str[len - (i + 1)] = rem + '0';
}
str[len] = '\0';
   }

【问题讨论】:

  • 您是否出于练习原因故意避开itoasprintf?因为他们几乎用一行替换了你所有的代码......
  • 是的@Amadan 我故意避免它。我想编写自己的代码来执行此操作。 :) 谢谢!
  • “我想编写自己的代码” - 那么您自己的代码在哪里,或者至少您自己对如何转换负值的想法?编程的一个重要部分是在实现之前先思考一下。这需要小学数学基础知识。

标签: c string integer logic


【解决方案1】:

在做任何其他事情之前,看看n 是否为负数。如果是,则以符号- 开始输出(确保len 也比其他情况多一个,并且您的字符串化稍后开始一个字符),使n 为正,然后照常继续以前做过。

【讨论】:

  • 我试过这样做,但它给了我奇怪的输出,类似于我不将负数转换为正数时得到的输出。
  • 那么请展示你在做什么。我们找不到我们没有被告知的错误。如果是为了练习,我只为你做会适得其反,所以我会一直提示你的代码,而不是自己写。
  • 我已经编辑了代码,这就是我得到的输入数字:-67 数字转换为字符串:*)
  • 请注意,您将n 转换为正数(顺便说一句,n = (-1)*(num)n = -num 相同),但您稍后使用num,而不是n,它仍然是负数(所以你最终会从'0' 中减去数字,而不是添加它们,这会产生奇怪的字符)。您也不要在str 中输入符号'-'
  • 谢谢,我想知道我怎么错过了那部分。我会尝试解决它。并将在此处更新相同的内容
【解决方案2】:

您必须像许多其他人所说的那样对“极端情况”保持警惕:

  • 在 int 中不能有负 int 的正值 int 的范围值是 [MIN; +MIN -1],如 –2,147,483,648 到 2,147,483,647 用于 4 字节整数。 所以,如果你有 –2,147,483,648 而你 *-1,你将不会有 2,147,483,648,因为它会溢出 int 容量

  • 您查找 int 的 len 的循环是“坏的”,因为您没有在计数中取负数(但我想这是本文的目的)并且您没有使用 car极端情况 0(“len”值为 0 但必须为 1)。

那么,如何实现这个功能呢?

1 : 修正 int len 计算

size_t len = 1;

for (int n = number;  n <= -10 || 10 <= n; n /= 10) {
    ++len;
}

2 : 修复“数字转字符”循环

for (size_t i = 0; i < len; ++i) {
    str[len - i - 1] = abs(number % 10) + '0';
    number /= 10;
}
str[len] = '\0';

那里。唯一剩下的就是在开头加上“-”,并为负数加上一个偏移量。 你可以有一个偏移变量(如果你使用它,修复“数字到字符循环”)或者你可以简单地做“++str”。

那里,你现在可以自己做这个功能了,我已经给你答案了。


有趣的是,如果您简单地执行以下操作,您可以跳过“abs”功能:

void tostring(char *str, int number)
{
    char   *digit = "9876543210123456789" + 9;
    size_t len    = 1;

    if (number < 0) {
        // TODO : Put '-' in the first case
        // TODO : Make str to be *str[1]
    }

    for (int n = number;  n <= -10 || 10 <= n; n /= 10) {
        ++len;
    }

    for (size_t i = 0; i < len; ++i) {
        str[len - i - 1] = digit[number % 10];
        number /= 10;
    }
    str[len] = '\0';
}

如果您不了解它的工作原理,请花点时间阅读指针的工作原理(尤其是指针运算)。

【讨论】:

  • 循环两次分频,最多可能需要 80 个时钟周期。
  • @P__J__ 你是什么意思?我知道在这种情况下,计算字符串的 futur len 有点没用,但是这个函数非常不安全,因为它使用“str”而不知道是否有足够的空间。所以这个函数的“更好”版本将不得不 malloc,然后有最终长度是有意义的(尽管你仍然可以只 malloc 64 char 并简单地反转最终字符串)。此外,我尝试保留 In-terra Weekend Projects 使用的相同算法。
【解决方案3】:

我在@Amadan 的帮助下解决了这个问题。 这是我正在使用的代码。请随时告诉我解决此问题的更好方法。 谢谢 拉贾特

/*
* C Program which Converts an Integer to String & vice-versa
 */
 #include <stdio.h>
 #include <string.h>
 #include <math.h>

 void tostring(char [], int);


 int main()
 {
     char str[10];
     int num, result;

     printf("Enter a number: ");
     scanf("%d", &num);
     tostring(str, num);
     printf("Number converted to string: %s\n", str);


     return 0;
  }

 void tostring(char str[], int num)
 {
     int i, rem, len = 0, n;
     bool flag=0;
     if(num<0)
   {
       n=-num;
       flag=1;
   }
     else
   {
       n=num;
       flag=0;
   }
   while (n != 0)
   {
       len++;

       n /= 10;


    }
   if(flag==1)
    {
        num=-1*num;
        str[0]='-';

     }

    for (i = 0; i < len; i++)
    {

        rem = num % 10;
        num = num / 10;
        if(flag==1)
        {
            str[len - (i)] = rem + '0';

        }
        else
        {
           str[len - (i + 1)] = rem + '0';
        }   



       }
       if(flag==1)
       {
           str[len+1] = '\0';
       }
       else
       {
           str[len] = '\0';
       }



    }

【讨论】:

  • 您只是不考虑许多人(包括我)告诉您的极端情况,所以我会说:您的代码有问题。也许修复它?
  • 谢谢汤姆!我实际上正在使用此函数将传感器数据转换为字符串,我知道该字符串始终在限制范围内。目前有点紧急,只要事情变得容易一些,我就会尝试解决这个问题。 :)
【解决方案4】:

只需使用sprintf函数如下,

sprintf(str,"%i",num);

所以修改后的代码会是,

#include <stdio.h>
#include <string.h>
#include <math.h>

void tostring(char [], int);


int main()
{
char str[10];
int num, result;

printf("Enter a number: ");
scanf("%d", &num);
//tostring(str, num);
sprintf(str,"%i",num);
printf("Number converted to string: %s\n", str);


return 0;
}

void tostring(char str[], int num)
  {
    int i, rem, len = 0, n;

n =num;
while (n != 0)
{
    len++;
    n /= 10;
}
for (i = 0; i < len; i++)
{
    rem = num % 10;
    num = num / 10;
    str[len - (i + 1)] = rem + '0';
}
str[len] = '\0';
   }

希望这会有所帮助。

【讨论】:

    【解决方案5】:

    这里你有一个适用于任何基数的函数(你只需要找到足够的字符来表示数字),但它不适用于一个极端情况(你能找到这种情况吗?)

    static const char Digits[] = "0123456789ABCDEFGHIJKLMNOPQRSTUWXYZ";
    
    static char *reverse(char *s, size_t len)
    {
        size_t pos;
    
        for(pos = 0; pos < len / 2; pos++)
        {
            char tmp = s[pos];
    
            s[pos] = s[len - pos - 1];
            s[len - pos - 1] = tmp;
        }
        return s;
    }
    
    char *toString(char *buff, int n, unsigned base)
    {
        int saved = n;
        char *savedbuff = buff;
    
        n = n < 0 ? -n : n;                       // <= there is one number which will cause problems. Which one?
        do
        {
            *buff++ = Digits[n % base];
            n /= base;
        }while(n);
        if(saved < 0) *buff++ = '-';
        *buff = 0;
        return reverse(savedbuff, buff - savedbuff);
    }
    
    int main()
    {
        char buff[50];
        printf("%s\n", toString(buff, -255,12)); // 12 base :)
        printf("%s\n", toString(buff, -976,10)); // 10 base 
        printf("%s\n", toString(buff, -976,8));  // or maybe octal ?
        return 0;
    }
    

    【讨论】:

    • DV?任何评论
    猜你喜欢
    • 2016-01-21
    • 2015-07-27
    • 2012-11-04
    • 2012-05-01
    • 1970-01-01
    • 2020-12-10
    • 1970-01-01
    • 1970-01-01
    • 2018-05-02
    相关资源
    最近更新 更多