2012-02-16 102 views
2

我想创建一个简单的程序,读取一个4位数的字符串,确保它确实是4位数,确保没有非数字,然后将前两个数字与最后两个数字分开并将它们相加。我可以把它所有的工作,但我仍然得到这个错误:ValueError:无效文字为int()与基数10为非数字

ValueError: invalid literal for int() with base 10:

这只有当我尝试一个字符串,如“456f”发生。

我可以改变什么来解决这个问题?

代码:

s = input('please type a 4-digit integer \n') 
valid = True 
for c in s: 
    if len(s)!= 4: 
     valid = False 
    if not c.isdigit(): 
     print (c, 'is not a valid input') 
number = int(s) 
firstOne = number // 100 
secondOne = number % 100 
sum = firstOne + secondOne 
x = '/' 
if valid == True: 
    print('your integer is ' + str(number), x, 'first two digits are ' + str(firstOne), x, 'second two digits are ' + str(secondOne), x, 'sum of two new numbers is ' + str(sum)) 
else: 
    print(len(s), 'is an invalid amount of digits') 

回答

3

让我们专注于这个代码:

for c in s: 
    if len(s)!= 4: 
     valid = False 
    if not c.isdigit(): 
     print (c, 'is not a valid input') 
number = int(s) 

首先要说的是,在len()检查应的字符循环外移动。

if len(s)!= 4: 
    valid = False 
for c in s: 
    ... 

下一个要做的评论是,当你检测到非数字时,你继续执行代码,就像没有任何错误一样。你大概打算将valid设置为False

if not c.isdigit(): 
    print (c, 'is not a valid input') 
    valid = False 

现在,问题的主要部分。当检测到无效输入时,您需要跳过转换为int

if valid: 
    number = int(s) 
    ... 

如果你想继续这样的做法你的代码应该是这样的:

valid = True 
s = input('please type a 4-digit integer \n') 
if len(s)!= 4: 
    valid = False 
    print(len(s), 'is an invalid amount of digits') 

if valid: 
    for c in s: 
     if not c.isdigit(): 
      valid = False 
      print (c, 'is not a valid input') 

if valid: 
    number = int(s) 
    firstOne = number // 100 
    secondOne = number % 100 
    sum = firstOne + secondOne 
    x = '/' 
    print('your integer is ' + str(number), x, 'first two digits are ' + str(firstOne), x, 'second two digits are ' + str(secondOne), x, 'sum of two new numbers is ' + str(sum)) 

说了这一切,我可能会重新组织代码颇有几分应对只要检测到错误,就会发生错误。如果你能以这种方式组织你的错误处理,代码将更容易理解。

s = input('please type a 4-digit integer \n') 
if len(s)!= 4: 
    sys.exit(str(len(s)) + ' is an invalid amount of digits') 
for c in s: 
    if not c.isdigit(): 
     sys.exit(c + ' is not a valid input') 
number = int(s) 
firstOne = number // 100 
secondOne = number % 100 
sum = firstOne + secondOne 
x = '/' 
print('your integer is ' + str(number), x, 'first two digits are ' + str(firstOne), x, 'second two digits are ' + str(secondOne), x, 'sum of two new numbers is ' + str(sum)) 

现在,这是一个正确的方向,但您仍然可以继续以这种方式让代码更好更好。 Sven's answer为您提供了一个很好的例子,说明这样一个过程最终会导致什么。

+0

这非常有帮助!非常感谢你。虽然你的解决方案似乎是最简单的,有没有什么办法可以维护我的代码中的有效和布尔逻辑,并仍然避开错误信息? – dustdustdust 2012-02-16 14:18:47

+1

@垃圾粉尘:如果你认为这个答案是最有用的答案(我认为是这样),考虑接受它。 – 2012-02-16 14:59:52

+0

@垃圾粉尘当然。我已经更新了答案,真正拼出来了。但我不能强调这是一个不好的解决方案。这个问题存在的事实表明了基于“if”的错误处理的问题。 – 2012-02-16 15:00:32

4

要检查所有的字符是否数字,但这个检查有没有后果 - 你而已矣,甚至当你发现无效字符。这会导致代码失败并显示带引号的错误消息。

我建议使用专用函数读取其重复询问,直到它得到了一个有效的输入整数:

def input_int_digits(prompt, digits=4): 
    while True: 
     s = input(prompt).strip() 
     if len(s) == digits and s.isdigit(): 
      return int(s) 
     print("Invalid input -- {}-digit integer expected.".format(digits)) 

注意我用了str.strip()除去开头或结尾whitepsace和str.isdigit()检查是否字符串的所有字符都是数字 - 您不需要循环字符串。

0

在isdigit的检查中,如果字符串包含非数字,但仍在所有s上调用int(),则会打印一条错误消息
需要在“不是有效输入”后退出程序消息

可以打印改为

sys.exit("is not a valid input") 
2

什么

... 
valid = len(s) == 4 and all(c.isdigit() for c in s) 
if not valid: 
    print (c, 'is not a valid input') 
... 

甚至更​​好(感谢,斯文!)

... 
valid = len(s) == 4 and s.isdigit() 
... 
+1

'all(c.isdigit()for c)'的简便快捷方式是's.isdigit()'。 – 2012-02-16 14:05:59