是否可以将前导零存储在 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。为此,请使用流操纵器 setw
和 setfill
。
【讨论】:
以上是关于是否可以将前导零存储在 int 中?的主要内容,如果未能解决你的问题,请参考以下文章