是否可以将前导零存储在 int 中?

Posted

技术标签:

【中文标题】是否可以将前导零存储在 int 中?【英文标题】:Is it possible to store a leading zero in an int? 【发布时间】:2012-10-17 19:58:39 【问题描述】:

我有一个编程任务,我需要加密一个 4 位整数,由用户输入。我已将 int 拆分为四个单独的值,并且加密和解密功能起作用。我的问题是当我将四个单独的整数重新组合在一起时,一些数字加密为零(例如 in:1234 out:0189),我想将输出存储到一个 int 中以用于其他函数。

现在我有一个半生不熟的解决方案,如果第一个 int 为 0,则首先打印 0。

void joinInt()
    if(int1 == 0) cout << 0;
    joined = int1 * 1000;
    joined += int2 * 100;
    joined += int3 * 10;
    joined += int4;
    cout << joined << endl;
    

我的目标是返回joined(前导零),而不仅仅是在函数中打印它。

【问题讨论】:

这些是否会延续到 int 中? 我认为有可能进行加密,这会导致多个前导零,例如 0012 或 0009 甚至可能是 0000。您只处理第一个数字的情况为零。请看下面我的建议,以了解可以处理这些情况的函数。 自然状态下的 int 不带前导零(技术上不正确,但为了论证,假设它不带前导零)。 1 是一个整数。 10 是一个整数。 0010 是整数的表示。这不是您需要更改的 int,而是您打印它的方式。 @RichardChambers 我完全错过了这种可能性。你给出的例子看起来很完美,它有点超出我的范围,但我要研究你做了什么。谢谢! @ThomasMcLeod 请注意the homework tag is now being phased out and must no longer be used。 【参考方案1】:

这样做:

#include <iomanip>
#include <iostream>

std::cout << std::setfill('0') << std::setw(4) << joined << std::endl;

【讨论】:

【参考方案2】:

int 包含一个数字。它不包含任何特定的表示信息,例如它是否是从包含一个前导零或两个的文本输入的,或者它是用十六进制、八进制还是鸡划痕编写的,或者即使它是通过添加一堆数字来计算的。它只是一个值。

如果要显示带有前导零的int,则必须以这种方式显式转换:

char buf [20];
snprintf (buf, sizeof buf, "%04d", myint);  // output base 10, + leading zeros
                                           // for a field width of 4

【讨论】:

+1 用于解释前导零与 int 的表示方式无关。 这取决于。如果有一个应用程序严重依赖显示 int 并且总是需要它们是固定宽度,而实际上显示操作比实际 int 算术重要得多(尽管这也需要支持,所以它们不能只是字符串),实际上使数据类型具有固定宽度可能很重要。例如,我可以看到这对于一些原始的小型电子产品很重要。我们都已经习惯了 int 类型的常见用例,以至于它的显示(正确地)与类型的规范高度解耦。但这不是普遍的真理...... 我想我是说有时有人要求数据类型int 具有数学整数不需要的额外的、特定于应用程序的属性是合理的。对于一般计算,这是非常不受欢迎的,但在重要的地方可能存在特定领域。所以我很犹豫是否支持“一个 int 包含一个数字”的想法。是的,一个 math 整数包含一个数字的表示。但是int 实例应该包含您系统中需要的任何内容。通常这是一个尽可能忠实于 math-int 的解耦对象。但并非总是如此。 @EMS:对于标记为c++ 的问题,这是一个不同寻常的观点。您的观点更适合数据处理系统工程或某些数学分支。 我致力于实现一个实时嵌入式系统(实际上是在 Python 中,但很多工作都是用 Cython 完成的),而我们正是需要它的地方。以不同方式存储 int 会更有效,因为它们只是用于显示目的和一些非常小的 int 算术。我认为这对于 C++ 和任何语言都没有什么不寻常的。我的观点是与语言无关。 int 数据类型不必与标准 int 数据类型相同。【参考方案3】:

int 基本上存储前导零。您遇到的问题是您没有打印那里的前导零。

另一种不同的方法是创建一个函数,该函数将接受四个 int 值和一个字符串,然后返回一个带有数字的字符串。

通过这种方法,您可以获得具有非常好的内聚力、无副作用、可在您需要完成类似操作的地方重复使用的辅助函数。

例如:

char *joinedIntString (char *pBuff, int int1, int int2, int int3, int int4)

    pBuff[0] = (int1 % 10) + '0';
    pBuff[1] = (int2 % 10) + '0';
    pBuff[2] = (int3 % 10) + '0';
    pBuff[3] = (int4 % 10) + '0';
    pBuff[4] = 0;                    // end of string needed.
    return pBuff;

然后在您需要打印值的地方,您可以使用参数和提供的字符缓冲区调用函数,然后打印字符缓冲区。

使用这种方法,如果您有一些不合理的数字最终有多个前导零,您将得到所有零。

或者您可能希望有一个函数将四个 int 组合成一个 int,然后另一个函数将打印组合后的 int 和前导零。

int createJoinedInt (int int1, int int2, int int3, int int4)

    return (int1 % 10) * 1000 + (int2 % 10) * 100 + (int 3 % 10) * 10 + (int4 % 10);


char *joinedIntString (char *pBuff, int joinedInt)

    pBuff[0] = ((joinedInt / 1000) % 10) + '0';
    pBuff[1] = ((joinedInt / 100) % 10) + '0';
    pBuff[2] = ((joinedInt / 10) % 10) + '0';
    pBuff[3] = (joinedInt % 10) + '0';
    pBuff[4] = 0;                    // end of string needed.
    return pBuff;

【讨论】:

再次感谢您的回答,我觉得您是唯一一个阅读并真正理解我的问题的人。【参考方案4】:

这应该可以解决问题。

cout << setw(4) << setfill('0') << joined << endl;

要使用这些操纵器,您需要:

#include <iomanip>

【讨论】:

【参考方案5】:

C++ 将int 存储为二进制数。但是所有 IO 都是字符串。因此,要显示int,必须将int 转换为字符串。在转换过程中,您可以从显示的数字中设置 with。为此,请使用流操纵器 setwsetfill

【讨论】:

以上是关于是否可以将前导零存储在 int 中?的主要内容,如果未能解决你的问题,请参考以下文章

在 C 中存储前导零

添加前导零 Python [重复]

有没有一种简单的方法可以将前导零添加到通过 std::to_string(int) 创建的字符串中?

Swift 中 Int 的前导零

将前导零附加到给定值[重复]

Python将前导零添加到时间字段[重复]