如何检查字符串是不是表示正的非零 int?
Posted
技术标签:
【中文标题】如何检查字符串是不是表示正的非零 int?【英文标题】:How Can I Check if a string represents an positive, non-zero int?如何检查字符串是否表示正的非零 int? 【发布时间】:2011-01-07 12:17:44 【问题描述】:我不需要知道 int 是什么,我只需要知道它是否是十进制表示中的正数、非零整数表示,没有前导 0。
需要大量记录,所以我希望它尽可能便宜。
预期的行为是系统不应该传递不验证的东西(因为它通常传递整数,它转换为字符串进行存储)所以这只是最后的安全检查,以确保没有发生任何奇怪的事情。
【问题讨论】:
我不明白你的最后一段 - 谁转换,谁验证以及为什么。读起来像您将 int 转换为字符串而不是验证转换? 您的整数的预期格式是什么?十进制、十六进制、八进制、科学记数法? 【参考方案1】:虽然您实际上可以完成将其实际转换为 int 的过程,但我的假设是您真正想知道的是其中的所有字符是否都是数字?
不幸的是,即使这样也别无选择,只能线性地遍历字符串,尽管这应该比先转换为整数更快。
使用 STL,您可以使用 std::find 和 ::isdigit 和 std::not1
template<typename FwdIter>
bool all_digits( FwdIter start, FwdIter end )
return std::find( start, end, std::not1(::isdigit) ) == end;
当然你可以只写一个循环
template<typename FwdIter>
bool all_digits( FwdIter start, FwdIter end )
for( ; start != end; ++start )
if( !::isdigit( *start ) )
return false;
return true;
这并不能完全告诉您输入字符串是否表示正数,因为它们可能全为零,并且字符串可能为空。我们可以很容易地在循环版本中覆盖它。
template<typename FwdIter>
bool is_positive_int( FwdIter start, FwdIter end )
bool foundNonZero;
for( ; start != end; ++start )
if( !::isdigit( *start ) )
return false;
if( *start > '0' ) // it must be a digit
foundNonZero = true;
return foundNonZero;
假设:
您可能有前导零(但有 必须至少是一个非零 那里)所以 0234 是一个有效的正面 号码 不允许有空格【讨论】:
完美。你实际上不应该有前导 0,但如果有一个以某种方式进入,那并不重要。 关于这一点的一点说明:我必须在 ::isdigit 周围创建一个函子包装器才能工作,以便定义 argument_type。【参考方案2】: 第一个字符必须是 1 到 9 中的一个 所有其他字符必须是 0 到 9 之一检查第一个,循环其余的,简单易行。
【讨论】:
第一个字符可能为零(例如,许多 C/C++ 代码会转储带有前导零的八进制数)。所以如果第一个数字是零,你需要继续检查数字。同样,一旦您找到第一个非零数字,其余的就无关紧要了,除非您正在解码该数字(或者您正在验证它只是一个数字)。 是八进制还是前导 0? 有多种表示形式。 1E9 意味着十亿呢?虽然这也可能意味着 489 如果它是十六进制。【参考方案3】:这确实很简单,但这取决于要求/允许的输入:
允许什么表示/基础:二进制、八进制、十六进制? (主要区别是十六进制,你的数字设置不同) 允许前导和尾随空格(您的输入是一个字符串,除非您被保证不会发生,否则您不应忽略这一点) 是否允许前导零? 是否允许前导+
?
根据上述情况,您可能需要:
去除前导和尾随空格 扫描字符串,检查它是否只包含允许的数字和+
验证它是否包含至少一个非零数字
问题也是您是否需要验证号码,例如输入123+456
如果需要,您可以编写一个简单的状态机来执行上述所有操作。
编辑
如果我了解您的要求,一个子系统会将正整数转换为字符串,这些字符串最终会到达另一个想要验证输入没有发生任何事情的子系统。如果您知道您的 int 到字符串的转换,那么任务会容易得多:假设没有空格、没有前导零、没有前导 +
,那么您的任务确实像第一个答案一样“简单易懂”:)
【讨论】:
以上是关于如何检查字符串是不是表示正的非零 int?的主要内容,如果未能解决你的问题,请参考以下文章