【问题标题】:Convert a string to int (But only if really is an int)将字符串转换为 int(但仅当确实是 int 时)
【发布时间】:2010-01-08 00:10:14
【问题描述】:

在大学时,有人问我我们的程序是否检测到从命令行参数输入的字符串是否是整数,而它没有检测到 (./Program 3.7)。现在我想知道如何检测到这一点。因此,例如 a 的输入是无效的,而 atoi 检测到,但是像 3.6 这样的输入应该是无效的,但 atoi 会将其转换为整数。

#include <stdio.h>

int main(int argc, char *argv[]) {
    if (argc > 1) {
        int number = atoi(argv[1]);
        printf("okay\n");
    }
}

但是只有当 argv[1] 真的是一个整数时才应该打印 offcourse OK。希望我的问题很清楚。非常感谢。

【问题讨论】:

  • 这几乎是今天早些时候提出的问题的重复。答案是一样的:使用strtol。它设置了一个指针,指向它所转换的内容的结尾——如果它不是“\0”,那么那里有一些东西无法转换。
  • 那是作业的微弱气味吗。
  • 你会认为 '1e6' 是一个整数吗?或(消除想法)'1.234e6'?最好不要去那里。
  • @rob:哈哈,这是家庭作业,已经评分 (8)。我想因为没有测试这个我得到了扣分。我只是想知道最短/最干净的。 @jerry 那是哪个线程?

标签: c integer validation strtol


【解决方案1】:

看看strtol

如果 endptr 不为 NULL,strtol() 将第一个无效字符的地址存储在 *endptr 中。但是,如果根本没有数字,strtol() 将 str 的原始值存储在 *endptr 中。 (因此,如果 *str 在返回时不是 \0' but **endptr is \0',则整个字符串都是有效的。)

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char *argv[]) {
  if (argc > 1) {
    char* end;
    long number = strtol(argv[1], &end, 0);
    if (*end == '\0')
      printf("okay\n");
  }
}

【讨论】:

  • 我看过 strtol 但我无法实现它来检测 3.6 作为无效输入..
  • 您在使用strtol 时遇到了哪些具体问题?您是否检查了返回时指针指向的值?
  • @gregory 谢谢格雷戈里。这正是我一直在寻找的,我认为代码非常密集。 @Pavel 我认为我没有做足够的错误检查我只是做了 strtol(argv[1], &end, 0);
【解决方案2】:

假设您想知道如何在代码中完成它(如果确实是家庭作业,则可能),一种方法是根据字符串考虑什么构成整数。很可能是:

  • 可选符号,+/-。
  • 必填数字。
  • 任意数量的可选数字(但要注意溢出)。
  • 字符串结束。

根据该规范,您可以编写一个为您完成工作的函数。

类似这样的伪代码将是一个好的开始:

set sign to +1.
set gotdigit to false.
set accumulator to 0.
set index to 0.
if char[index] is '+':
    set index to index + 1.
else:
    if char[index] is '-':
        set sign to -1.
        set index to index + 1.
while char[index] not end-of-string:
    if char[index] not numeric:
        return error.
    set accumulator to accumulator * 10 + numeric value of char[index].
    catch overflow here and return error.
    set index to index + 1.
    set gotdigit to true.
if not gotdigit:
    return error.
return sign * accumulator.

【讨论】:

    【解决方案3】:

    【讨论】:

    • 不,不是。宝宝做 3 个。
    【解决方案4】:
    int okay = argc>1 && *argv[1];
    char* p = argv[1];
    int sign = 1;
    int value = 0;
    if( *p=='-' ) p++, sign=-1;
    else if( *p=='+' ) p++;
    for( ; *p; p++ ) {
        if( *p>='0' && *p<='9' ) {
            value = 10*value + *p-'0';
        } else {
            okay = 0;
            break;
        }
    }
    if( okay ) {
        value *= sign;
        printf( "okay, value=%d\n", value );
    }
    

    编辑:允许 - 和 + 字符

    您甚至可以将其压缩成密集的单层或两层。或者您可能会找到具有相同功能的库函数;)

    EDIT2:只是为了好玩 - 它现在应该解析数字

    【讨论】:

    • 查看我对基于 strtol 的实现的回答,没有理由重新发明(方形)轮子 :)
    • 呵呵 我测试了这段代码,但它不起作用。首先,因为 false 并不是 c 的一部分。但我认为你的方向是正确的;)。当没有提供参数时,它也会抛出分段错误。
    • @Carl:d'oh,会改变它...,@Alfred:再次,d'oh
    • @Frunsi 我想这将是一件明智的事情,因为现在这段代码会在你面前爆炸(所以请更新代码以使其对其他 stackoverflow 成员正确)。
    • 大声笑,我会给strtol 解决方案+1。我只是尝试了一种快速而肮脏的方法,而当前的方法甚至应该可以工作。另请注意:它是一个片段,没有函数,没有程序,因此仍然需要检查有效数量的参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-30
    • 1970-01-01
    • 2011-10-02
    • 2011-03-06
    • 1970-01-01
    • 2018-07-05
    相关资源
    最近更新 更多