Simple C Code Error
有谁知道为什么我在运行这段代码时会出现段错误? Valgrind 告诉我,我在第 13 行 if( !isdigit(x) ) 上有”大小为 4 的未初始化值”,并且在同一行上有一个无效的读取大小 2 – 地址不是堆栈//’d,malloc//’d ,或免费的。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdbool.h>
int main() { int x;
printf("Please enter a number:"); scanf("%d", &x);
if( !isdigit(x) ) { printf("You entered %d/ ", x); } else { printf("You did not enter a valid number!/ "); }
return 0; } |
- isdigit 用于处理字符值;例如,对于 ‘1’ 的输入,它将返回 true,对于 ‘a’ 的输入,它将返回 false。你要输入什么?
- 如果您使用 %d,则 isdigit() 不会以您希望的方式工作。例如,如果输入 1,x 将不包含字符 1 的 ASCII 码,因此 isdigit() 将返回 false。
- 请记住始终检查输入是否成功:scanf(…) == 1?
- 不相关,但如果输入不是数字,scanf 将失败。因此,您可以将其替换为 scanf 的结果,而不是检查 “isdigit”。
- “得到一个段错误” – 这不是一个段错误。
我用 g 编译了你的代码,导致没有段错误。
输入值:
5、-1、27、43545gbb 和 gggg
产生的结果:
5、-1、27、43545 和 1729208414
-
您的输入会导致未定义的行为。您没有遵守 isdigit 的先决条件。更不用说从最后的输出中可以清楚地看出您正在使用未初始化的变量。简而言之,虽然这对您(现在)没有段错误,但它可以在任何时候。
我认为问题在于如果 scanf 失败,x 将未初始化。
最好在字符数组中输入数据。否则,您的代码没有意义,因为您无法在 int 类型的对象中输入非数字。此外,如果您输入一个数字,使用函数 isdigit 的结果可能会出乎意料。
- 我不认为是解决方案。例如,如果你用零值初始化 x,然后输入”dkj”,输出将是你输入了 0。这不是他想要的。当然,使用默认值初始化变量始终是一个好习惯。谢谢。
尝试以下方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() { int x = 0; char a;
printf("Please enter a number:");
while(scanf("%d%c",&x,&a) != 2 || a != ‘/ ‘) { printf("Please enter an integer only :"); do { scanf("%c",&a); }while(a != ‘/ ‘); }
printf("You entered %d/ ", x); return 0; } |
代码向您展示了如何使用 scanf 的复杂方法。有关更多信息:scanf 的工作并检查输入是否为 int
根据 c 文档:isdigit
原型:
参数:
1
|
ch – character to classify
|
目的:
Checks if the given character is a numeric character (0123456789).
The behavior is undefined if the value of ch is not representable as unsigned char and is not equal to EOF.
返回值:
Non-zero value (true) if the character is a numeric character, 0 (false) otherwise.
为什么第 13 行出现问题?第 13 行是 if( !isdigit(x) )
在第 8 行创建 x 时,您没有初始化它,
因此,如果输入了一个不可接受的值,并在第 11 行由 scanf() 处理,则它将在到达 isdigit() 函数时继续未初始化。
问题在于 isdigit() 期望输入必须是整数值介于 0 和 255 之间的字符。任何其他值都会导致未定义的行为。段错误是未定义行为的可能结果之一。
还有其他方法可以实现这一点,例如:
这是一个使用 char 数组(字符串)的示例。请注意注释以解释为什么要完成某些事情。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
|
int main ()
{
//int x;
char x [2]; //Good for only one digit
printf("Please enter an integer with up to 10 digits:"); //scanf("%d", &x); scanf("%1s", x); //Edited to allow maximum field width of 1.
// if( !isdigit(x) ) if( isdigit(x[0]) ) //note the"!" was removed for logic to work { printf("You entered %d/ ", atoi(x)); //note use of atoi() to convert string to int. } else { printf("You did not enter a valid number!/ "); }
return 0; } |
- isdigit 采用 int。只是你给它的 int 必须在 unsigned char 或 EOF 的范围内。
- 当您可以检查 if scanf(%d)==1 时,为什么要读取字符串并进行转换?
- @prajmus – 是的, scanf() 会工作。但是一个字符数组也是如此。由于 isdigit() 是一个字符测试器,我认为最好以 char 类型为例来说明使用该函数。此外,这里的核心问题是为什么会出现段错误?这可以通过解决作??为参数传递给 isdigit 的非法值来解决。
- char x[2]; scanf(“%s”, x); – 没有。
- @MattMcNabb – 使用扩展缓冲区进行编辑。让我知道这是否不是问题所在。谢谢。
- @ryyker 并没有更好,它仍然有缓冲区溢出。在 scanf 中使用最大字段宽度修饰符。
- @MattMcNabb – 已编辑,谢谢。仍在学习 scanf() 格式说明符的变体。感谢帮助。
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/269355.html