在c ++中将字符串转换为整数而不会丢失前导零

时间:2013-06-27 00:42:04

标签: c++

你好我将一串数字转换为整数有问题。 问题是使用atoi()将字符串转换为整数我松散前导零。 你能告诉我一种方法吗,而不会失去领先的零点吗?

#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>


using namespace std;

struct Book{
    int id;
    string title;
};

struct Author{
    string firstName; 
    string lastName;
};

Author authorInfo[200];
Book bookInfo[200];

void load ( void )
{

    int count = 0;
    string temp;

    ifstream fin;
    fin.open("myfile.txt");

    if (!fin.is_open())
    {
        cout << "Unable to open myfile.txt file\n";
        exit(1);
    }

    while (fin.good())
    {   
        getline(fin, temp, '#');
        bookInfo[count].id = atoi(temp.c_str());
        getline(fin, bookInfo[count].title, '#');
        getline(fin, authorInfo[count].firstName, '#');
        getline(fin, authorInfo[count].lastName, '#');
        count++;
    }

    fin.close(); 
}

7 个答案:

答案 0 :(得分:4)

好的,所以我认为你实际上并不想存储前导零。我想你想在输出中显示一致的位数。

因此,例如,要显示一个固定大小的id,包含5位数[请注意,100000的ID仍将显示为6位数 - 这里所做的只是确保它始终至少为5位数,并且如果数字不够大,请填写'0',我们可以这样做:

std::cout << std::setw(5) << std::setfill('0') << id << ... 

或者,正如其他答案中所建议的那样,您不希望以整数形式使用ID,您可以将其存储为字符串 - 除非您要对其进行数学运算,所有这一切变化是每本书占用的内存要多一点。

答案 1 :(得分:3)

整数没有前导零。或许,更准确地说,它介于零和无限数量之间。数字42,042和000000042(除了在前导0表示不同基数的源代码中)都是四十二。

如果要保留前导零,请将其保留为字符串,或者在原始字符串有多大的位置存储更多信息。这样的事情将是一个良好的开端:

#include <iostream>
#include <iomanip>
#include <cstring>
#include <cstdio>
#include <cstdlib>

int main (void) {
    // Test data.

    const char *sval = "0042";

    // Get original size.

    int size = strlen (sval);

    // Convert to int (without leading 0s).
    // strtol would be better for detecting bad numbers.

    int ival = atoi (sval);

    // Output details.

    std::cout << sval << " has size of " << size << ".\n";
    std::cout << "Integer value is " << ival << ".\n";
    std::cout << "Recovered value is " << std::setw(size)
        << std::setfill('0') << ival << ".\n";

    return 0;
}

输出:

0042 has size of 4.
Integer value is 42.
Recovered value is 0042.

答案 2 :(得分:2)

A = strlen(string)返回字符串中的字符数(比如前导零的综合位数)

B = log10(atoi(string)) + 1会返回您号码中的位数

A - B =>前导零的数量。

现在您可以根据需要设置格式。

答案 3 :(得分:2)

数字中没有“前导零”这样的东西。 “前导零”是特定表示法的属性,如数字的十进制ASCII表示。将该表示法转换为概念上抽象的数字表示后,“前导零数”等指标不再适用(至少以十进制表示)。它没有任何痕迹。

数字是一个数字。它没有任何“零”,领先或其他。

你唯一能做的就是记住原始符号中有多少前导零(或者字段的宽度),然后,当你将数字转换回十进制ASCII表示时,重新创建使用存储的信息的正确零的正确数量。

顺便说一句,在您的情况下,当输入数字表示具有某些预定格式的图书ID(如前导零)时,您可能会考虑采用不同的方法:不要将图书ID转换为int。把它保持为一个字符串。这不像你将不得不对书籍ID进行算术运算,是吗?最有可能你需要的是关系和相等比较,这可以在字符串上执行。

答案 4 :(得分:1)

上个月我遇到过这类问题!

我认为您可以使用Class CString提供的Format()方法: CString::Format()在CString中格式化并存储一系列字符和值。每个可选参数(如果有)都根据pszFormat中相应的格式规范或nFormatID标识的字符串资源进行转换和输出。 例如:

CString m_NodeName;
m_NodeName.Format(_T("%.4d"),Recv[2]*100+Recv[3]);
// %.4d means the argument will be formatted as an integer, 
// 4 digits wide, with unused digits filled with leading zeroes

您可以在此处找到详细信息: http://msdn.microsoft.com/zh-cn/library/18he3sk6(v=vs.100).aspx

答案 5 :(得分:0)

如果您需要前导零,则int不是要使用的正确数据类型。在你的情况下,你可能最好只存储原始字符串。

答案 6 :(得分:0)

无法存储前导0的int

您可能想要做的事情是class为您做这件事:

 class intWithLeadingZeros {
       int number;
       int numberOfLeadingZeros;

       intWithLeadingZeros( string val )
       {
          // trivial code to break down string into zeros and number
       }

       string toString() {
            // trivial code that concatenates leading 0s and number
       }



 };