【问题标题】:Put integer variable in string manually手动将整数变量放入字符串中
【发布时间】:2015-04-03 00:44:14
【问题描述】:

我有一个关于以下代码的快速问题

int main()
{
    string data;
    int x;
    cin >> x;

    if (x < 0)
    {
        data = to_string(x);
    }
    else
    {
        data = to_string(x);
    }
   return 0;
}

如果我不想使用to_string(x),我想手动做一些事情。反正我能做到吗?如果我使用data = x;,这显然行不通。

ps。我也不想用atoi

【问题讨论】:

    标签: c++ string integer


    【解决方案1】:

    您可以执行以下操作:

    int main(){
        int x;
        cin>>x;
        string s = "";     // s will represent x but with the digits reversed
        bool neg = 0;      // this flag is 1 if x is negative and 0 if positive. 
                           // we will use it to find out if we should put a "-" before the number
        if(x < 0){
            neg = 1;
            x *= -1;       // making the number positive
        }
        while(x){
            char c = '0' + x % 10;          // c represent the least significant digit of x
            s.push_back(c);                 // adding c to s             
            x /= 10;                        // removing the least significant digit of x
        }
        string ans = "";                    // ans is our resulting string
        if(neg) ans.push_back('-');         // adding a negative sign if x was negative
        for(int i=s.size() - 1; i >= 0; i--)    // adding the characters of s in reverse order
            ans.push_back(s[i]);
    }
    

    【讨论】:

    • 如果std::to_string 不符合“手动”条件,我不明白这会如何。
    • 抱歉,没注意。我会修改我的代码。
    • 数字倒序的原因是什么?
    • x%10 将返回 0 到 9 之间的整数。但我们需要一个字符来表示整数。在 ASCII 表 (en.wikipedia.org/wiki/ASCII) 中,我们有从 0 开始的数字序列(0、1、2、3、4、5、6、7、8、9)。因此,如果我们将 ASCII 值“0”添加到 0 到 9 之间的整数 x,我们将得到一个字符,其 ASCII 值表示整数 x。
    • x%10 返回 x 的最低有效位。所以 123%10 将返回 3。我们将 3 保存在 s[0] 中,但在最终字符串中,3 应该在最后一个索引中。
    【解决方案2】:

    这可能就足够了。

    string convertInt(int number)
    {
        if (number == 0)
            return "0";
        string temp="";
        string returnvalue="";
        while (number>0)
        {
            temp+=number%10+'0';
            number/=10;
        }
        for (int i=0;i<temp.length();i++)
            returnvalue+=temp[temp.length()-i-1];
        return returnvalue;
    }
    

    (这个函数不是我写的,而是通过做一个quick Google search找到的。原帖is here。)

    此函数通过将数字除以 10 来工作。它获取除法的余数,该余数始终介于 0 和 9 之间。然后它通过添加字符 @987654325 的整数值来“找到”表示该数字的字符@给它。

    接下来,它取那个除法的商,并一次又一次地执行相同的操作,直到商为零。

    这会产生一个字符串,其中包含表示数字的字符,但顺序相反。最后一个循环在返回之前反转字符串。

    正如 chris 在下面的 cmets 中指出的那样,数字 0 到 9 保证按顺序排列

    N3485, §2.3 [lex.charset]/3:在源代码和执行基本 字符集,上面列表中0后每个字符的值 小数位数应比前一个值大一。 (上面的列表很直观地是 0 1 2 3 4 5 6 7 8 9)。

    这是关于字符串操作的好读物:The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

    【讨论】:

    • 不知道为什么投反对票。这正如 OP 所要求的那样,没有真正调用另一个函数来完成这项工作。
    • 我没有投反对票,但可以看出原因。该代码采用特定的字符集 (ASCII),不会与其他字符集一起使用。完成这项工作的方法也少得多。
    • 与其在使用难以理解的数字时警告它不能与其他字符集一起使用,除非你知道 '0' 在 ASCII 中是 48,为什么不直接使用 '0' ? '0''9' 保证在字符集中是连续的,'0' 传达的意思要好得多,现在代码可以移植(并不是说依赖 ASCII 对 99% 的代码真的有影响)。
    • 其他数字可能不仅仅是接下来的 9 个字符,它仍然可能失败。
    • @Steve,对不起,编辑了我的评论,但确实如此。即使它们不是,您也可以通过相同的假设获得更高的可读性,并且不再将“0”表示为 48 假设。
    【解决方案3】:

    以任何数字为基数手动格式化整数并不难。例如。以 10 为基数:

    void print(int n)
    {
        if (n == 0) { std::cout << '0'; return; }
        if (n < 0) { std::cout << '-'; n = -n; }
    
        std::string buf;
        while (n != 0) { buf += '0' + n % 10; n /= 10; }
        for (auto it = buf.rbegin(); it != buf.rend(); ++it)
            std::cout << *it;
    }
    

    如果您的数字基数大于 10,您必须提供合适的字母表并使用 n % base 枚举所需的数字。

    如果你想避免重新分配,你可以在字符串中预留容量,你可以通过取一个合适的n的对数来计算所需的容量。

    【讨论】:

      【解决方案4】:

      如果你真的必须自己提取数字

      std::string manual_convert(int value)
      {
          if (x < 0)
             return std::string("-") + manual_convert(-x);   // handle negative values (except potentially INT_MIN)
          else if (x == 0)
             return "0";
      
          std::string retval;
          while (x > 0)
          {
               char digit = x%10 + '0';     // extract the proverbial digit
               retval.append(1, digit);
               x /= 10;                     // drop the digit, and prepare for next one
          }
      
          std::reverse(retval.begin(), retval.end());   // loop above extracted digits in reverse order
          return retval;
      }
      

      【讨论】:

        【解决方案5】:

        两种简单的方法:

        #include <sstream>
        string intToString(int x)
        {
           stringstream stream;
           stream << x;
           return stream.str();
        }
        

        或者如果你使用 boost 库

        string str = lexical_cast<string>(x)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-08-14
          • 1970-01-01
          • 2016-08-29
          • 2011-12-09
          • 1970-01-01
          • 2020-05-31
          相关资源
          最近更新 更多