以下代码如何发生堆栈粉碎错误?

时间:2019-02-26 05:24:16

标签: c

我编写了以下程序来查找输入数字(n)的位数之和,该数字的总和小于该数字的第一位数(sumlessfirst(n)函数)或输入的数字(n)小于用户定义的数字(x)(sumlessinput(n,x)函数)。用户必须输入“ first”才能使用sumlessfirst(n)功能,或者输入“ custom”才能使用sumlessinput(n,x)。但是在编译时,该代码将用户的输入输入为“ first”或“ custom”,然后显示堆栈粉碎错误。是什么原因造成的?

#include <stdio.h>
int sumlessfirst(int n)
{
    int i, j = n, sum = 0, sum1 = 0, count = 0;
    for (i = n; i > 0; i = i / 10)
    {
        count = count + 1;
    }
    while (count >= 2)
    {
        j = j / 10;
        count = count - 1;
    }
    int k;
    for (k = n; k > 0; k = k / 10)
    {
        if (k % 10 > j)
        {
            sum1 = sum1 + k % 10;
        }
    }
    printf("The sum of digits less than the first digit off %d is %d\n", n, sum1);
    return 0;
}

int sumlessinput(int n, int x)
{
    int i, sum;
    for (i = n; i > 0; i = i / 10)
    {
        if (i % 10 > x)
        {
            sum = sum + i % 10;
        }
    }
    printf("The sum of digits greater than %d of %d is %d\n", x, n, sum);
    return 0;
}

int main()
{
    int n, x;
    char s[100];
    printf("Enter whether you want to go for the first digit or go for a custom value\n");
    printf("If you wanna go for first digit, enter first\n");
    printf("Tf you wanna go for custom input, enter custom\n");
    scanf("%s", &s[100]);
    if (s == "first" || s == "First")
    {
        printf("Enter the number: ");
        scanf("%d", &n);
        sumlessfirst(n);
    }
    else if (s == "custom" || s == "Custom")
    {
        printf("Enter the number: ");
        scanf("%d", &n);
        printf("Enter the custom value: ");
        scanf("%d", &x);
        sumlessinput(n, x);
    }
}

我得到的错误是:

Enter whether you want to go for the first digit or go for a custom value
If you wann go for first digit, enter first
If you wann go for custom input, enter custom
custom
*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)

3 个答案:

答案 0 :(得分:1)

问题是Cloneable

scanf()

您的代码正在调用int main() { int n,x; char s[100]; printf("Enter whether you want to go for the first digit or go for a custom value\n"); printf("If you wanna go for first digit, enter first\n"); printf("If you wanna go for custom input, enter custom\n"); scanf("%s", &s[100]); // <-- HERE if (s == "first" || s == "First") // <-- WRONG TOO { ... ,告诉它将字符串读取到变量scanf()的第101个字节中,该字符串只有100个字节(索引0-> 99)。

此呼叫应为:

s

或者只是:

scanf("%s", &s[0]);

下一行也不正确。像这样简单地比较两个字符串是无效的。这是因为在scanf("%s", s); 中,字符串解析为一个指针,并且此代码成为两个指针比较。因此,无论指针可能指向什么字符串内容,指针本身都是不同的。

您可能正在使用C函数:

strcmp()

或者,只需检查第一个字母:

if (strcmp(s, "first") == 0)  # TODO handle capitalisation
{
    ...

答案 1 :(得分:1)

您将s的最后一个元素的地址传递给scanf()。您必须传递第一个元素的地址:

scanf("%s", s);

此外,请不要在未指定"%s"的情况下使用转换说明符width来限制写入数组的字符数,以避免缓冲区溢出:

scanf("%99s", s);  // no more than 99 character + the terminating '\0'

正如@Kingsley所说,使用strcmp()比较两个字符串。

答案 2 :(得分:0)

C语言中的数组具有从zerosize - 1的索引,因此您要声明type arr[100]索引为100的元素在数组之外