Как следующий код имеет ошибку разрушения стека? - PullRequest
0 голосов
/ 26 февраля 2019

Я написал следующую программу, чтобы найти сумму цифр входного числа (n), которые меньше первой цифры номера (функция sumlessfirst(n)) или сумму цифр входного числа (n), которые меньше определенного пользователем числа (x) (функция sumlessinput(n,x)).Пользователь должен ввести «первый», чтобы перейти к функции sumlessfirst(n), или ввести «пользовательский», чтобы перейти к sumlessinput(n,x).Но после компиляции код принимает ввод от пользователя как «первый» или «пользовательский», а затем показывает ошибку разрушения стека.Каковы причины этого?

#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 голосов
/ 26 февраля 2019

Вы передаете адрес элемента «один за другим» s на scanf().Вы должны передать адрес первого элемента:

scanf("%s", s);

Кроме того, НИКОГДА не используйте спецификатор преобразования "%s" без указания width, чтобы ограничить число символов, которые записываются в массив, доизбегайте переполнения буфера:

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

Как сказал @Kingsley, используйте strcmp() для сравнения двух строк.

0 голосов
/ 26 февраля 2019

Массивы в C имеют индексы от zero до size - 1, поэтому вы объявляете type arr[100] элемент с индексом 100 вне массива

0 голосов
/ 26 февраля 2019

Проблема в 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-й байт переменной s, что составляет всего 100 байт (индекс0 -> 99) долго.

Этот вызов должен быть:

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

Или просто:

scanf("%s", s);

Следующая строка также неверна.Недопустимо просто сравнивать две строки, подобные этой.Это связано с тем, что в C строки преобразуются в указатель, и этот код становится двумя сравнениями указателей.Поэтому независимо от того, на какое строковое содержимое могут указывать указатели, сами указатели различаются.

Возможно, вы используете функцию strcmp():

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

Или, в качестве альтернативы, просто проверьтепервая буква:

if ( s[0] == 'F' || s[0] == 'f' )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...