2

您好,我在将一串数字转换为整数时遇到问题。问题是使用 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(); 
}
4

7 回答 7

4

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

因此,例如,要显示一个 5 位数的固定大小的 id [请注意,id of100000仍将以 6 位显示 - 它在这里所做的只是确保它始终至少为 5 位,如果数量不够大],我们可以这样做:

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

或者,正如其他答案中所建议的那样,您不想以整数形式使用 ID,您可以将其存储为字符串 - 除非您要对其进行数学运算,否则它所改变的只是每本书占用更多的内存。

于 2013-06-27T00:51:16.893 回答
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.
于 2013-06-27T00:47:44.813 回答
2

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

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

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

现在您可以根据需要格式化它们。

于 2013-06-27T00:50:02.190 回答
2

数字中没有“前导零”之类的东西。“前导零”是特定符号的属性,例如数字的十进制 ASCII 表示。一旦将该符号转换为概念上抽象的数字表示,“前导零的数量”之类的度量就不再适用(至少以十进制表示)。它消失得无影无踪。

一个数字就是一个数字。它没有任何“零”,无论是前导还是其他。

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

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

于 2013-06-27T01:33:11.680 回答
1

我上个月就遇到过这种问题!

我认为您可以使用 Class CString 提供的 Format() 方法:在 CString CString::Format()中格式化和存储一系列字符和值。每个可选参数(如果有)都根据 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

于 2013-06-27T01:26:07.833 回答
0

无法存储int前导 0 的值。

您可能想要做的是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
       }



 };
于 2013-06-27T00:50:18.040 回答
0

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

于 2013-06-27T00:47:55.710 回答