Как исправить «Ошибка отладки!, стек вокруг переменной ‘x’ поврежден»?

#c #if-statement #char

#c #if-оператор #символ

Вопрос:

Я действительно новичок в языке C и тестировал простую программу if-statement, которая, исходя из вашего возраста и пола, сообщает один ответ из 4 разных результатов.

Это звучит примерно так: если вам меньше 55 лет и вы мужчина, будет напечатано: «Вы мужчина в лучшем возрасте!»

Но я сталкиваюсь с кодом ошибки, который гласит: ошибка проверки во время выполнения # 2 — Стек вокруг переменной ‘miesVaiNainen’ поврежден.

Я сам думаю, что это может иметь какое-то отношение к: if (manOrFemale == "f" amp;amp; age <= 55)

Как я могу исправить эту проблему, чтобы ошибка не появлялась?

Я пытался обратиться за помощью в stackoverflow и много раз пытался изменить код.

     int age;
    char manOrFemale;

    printf("Are you a man or a female(m/f)");
    scanf("%s", amp;manOrFemale);

    printf("Input age:");
    scanf("%d", amp;age);

    if (manOrFemale == "f" amp;amp; age <= 55)
    {
        printf("nYou are a lady at her best!");
    } else if (manOrFemale == "f" amp;amp; age >= 56)
    {
        printf("nYou look young for your age!");
    }


    if (manOrFemale == "m" amp;amp; age <= 55)
    {
        printf("nYou are a man at his best age!");
    } else if (manOrFemale == "m" amp;amp; age >= 56)
    {
        printf("nYou are a wise man!");
    } else {
        printf("There has been an error in the program!");
    }
}
  

Ответ №1:

На данный момент вы используете %s спецификатор для чтения char . для чтения вам нужно использовать %c спецификатор char , %s is for char * .

   scanf(" %c", amp;manOrFemale);
  

И

для сравнения нужно использовать одинарные кавычки chars . На данный момент вы сравниваете char с указателем.

 if (manOrFemale == 'f'; amp;amp; age <= 55)
  

Ответ №2:

Вот очень большая проблема:

 scanf("%s", amp;manOrFemale);
  

Переменная manOrFemale представляет собой один символ. Формат "%s" предназначен для чтения байтовых строк с нулевым завершением.

Строка, состоящая только из одного символа, требует места для двух символов, чтобы соответствовать нулевому терминатору. Поскольку у вас нет места для терминатора, scanf функция будет записывать данные в память, которой вы не владеете, что приведет к переполнению стека (где компиляторы обычно хранят локальные переменные), что приведет к получению ошибки.

Если вы хотите прочитать один символ, используйте "%c" формат, как в

 scanf(" %c", amp;manOrFemale);
  

Обратите внимание на начальный пробел в строке формата, он необходим, чтобы игнорировать возможные начальные пробелы (например, новые строки из любого предыдущего ввода).


Также обратите внимание, что при сравнении manOrFemale == "f" вы сравниваете один символ manOrFemale со строкой "f" . Литеральная строка в C — это действительно массив символов, доступный только для чтения, и, как и любой массив, он распадается до указателя на его первый элемент. Итак, вы не сравниваете символы, вы сравниваете символ с указателем.

Ваш компилятор должен был предупредить вас об этом.

Чтобы решить эту проблему, вам нужно сравнить с одним символом вместо этого : manOrFemale == 'f' . Обратите внимание на использование одинарных кавычек вместо этого.


Наконец, более стилистическое замечание…

Инструкции

 if (manOrFemale == 'f' amp;amp; age <= 55)
{
    printf("nYou are a lady at her best!");
} else if (manOrFemale == 'f' amp;amp; age >= 56)
{
    printf("nYou look young for your age!");
}
  

может быть переписано как

 if (manOrFemale == 'f')
{
    if (age <= 55)
        printf("You are a lady at her best!n");
    else
        printf("You look young for your age!n");
}
  

Здесь следует отметить еще одну вещь: я использую завершающий перевод строки в выходных данных. Это потому, что в противном случае после завершения программы может не быть новой строки (поэтому вывод, похоже, смешивается с командной строкой), а также потому, что вывод в stdout (куда printf записывается) по умолчанию буферизуется по строке. Буферизация строк означает, что выходные данные буферизуются внутри и фактически не записываются в терминал до тех пор, пока буфер не будет заполнен или не будет записана новая строка. Если вы используете в выводе начальные символы новой строки, то будет записана предыдущая строка, а не текущая строка.

Комментарии:

1. Вам тоже спасибо :)!. Я использую CLion от Jetbrain с лицензией для студентов.