Как мне избавиться от ошибки «сигнал: ошибка сегментации (ядро сброшено)» в C++, replit?

Я пытаюсь распечатать 1-999 в английском формате, используя слова.

Пример:
Ввод: 563
Выход: Five Hundred Sixty Three

Я сделал функцию для чисел от 1 до 9, от 10 до 19 и чисел, оканчивающихся на 0 до 99 (20, 30, 40, 50... 90), и у меня есть отдельная функция для 100.

У меня есть несколько функций, а затем одна main() функция. В последней функции я вызвал все предыдущие функции. Кроме того, у меня нет возвращаемого значения для моих функций.

При запуске возникает ошибка:

сигнал: ошибка сегментации (дамп ядра)

Может кто-нибудь, пожалуйста, помогите мне исправить это? И объясните как это сделать?

Это мой код:

#include <iostream>
using namespace std;

string digit_name(int digit) {
  // defines 1 through 9 
  if (digit == 1){
    return "One "; 
  }
  if (digit == 2){
    return "Two "; 
  }
  if (digit == 3){
    return "Three "; 
  }
  if (digit == 4){
    return "Four "; 
  }
  if (digit == 5){
    return "Five "; 
  }
  if (digit == 6){
    return "Six "; 
  }
  if (digit == 7){
    return "Seven "; 
  }
  if (digit == 8){
    return "Eight "; 
  }
  if (digit == 9){
    return "Nine"; 
  }
}

string teen_name(int number){
  // defines 10 through 19
  if (number == 10){
    return "Ten "; 
  }
  if (number == 11){
    return "Eleven "; 
  }
  if (number == 12){
    return "Twelve "; 
  }
  if (number == 13){
    return "Thirteen "; 
  }
  if (number == 14){
    return "Fourteen"; 
  }
  if (number == 15){
    return "Fifteen"; 
  }
  if (number == 16){
    return "Sixteen"; 
  }
  if (number == 17){
    return "Seventeen"; 
  }
  if (number == 18){
    return "Eighteen"; 
  }
  if (number == 19){
    return "Nineteen"; 
  }
}

string teens_name (int number){
  // defines 20 through 90 (20, 30, 40 ... 90)
  if (number == 20){
    return "Twenty "; 
  }
  if (number == 30){
    return "Thirty "; 
  }
  if (number == 40){
    return "Forty "; 
  }
  if (number == 50){
    return "Fifty "; 
  }
  if (number == 60){
    return "Sixty "; 
  }
  if (number == 70){
    return "Seventy "; 
  }
  if (number == 80){
    return "Eighty "; 
  }
  if (number == 90){
    return "Ninty "; 
  }
}

string hun_name (int number){
  // defines 100
  return "Hundred ";
}
  
string define (int number){
  // defines what it will output based on the input of the user
  // if 1 through 9, output the name (ex: One)
  if (number > 0 && number < 9){
    cout << digit_name(number);
  }
  
  // if 10 through 19, output name (ex: Seventeen)
  if (number >> 9 && number << 20){
    cout << teen_name(number);
  }

  // if number divides by 100, then it will print digit_name, then Hundred, and then the teens_name
  if (number/100){
    cout << digit_name(number) << "Hundered " << teens_name(number) << digit_name(number);
  }
  
  // if number divides by 10 evenly, then it is one of the teens (ex: Sixty)
  if (number/10 == 0){
    cout << teens_name(number);
  }

  // else, it is a number from 21-99, so it will print teens_name and then digit_name
  else{ 
    cout << teens_name(number) << digit_name(number);
  }
}

// main function - approved by Ms. B
int main() {
  int num;
  cout << "Please enter a number from 1 - 999: ";
  cin >> num;
  define (num);
}

1) Ты забыл #include <string>. 2) Вы игнорируете предупреждения компилятора? Вы объявили функции, которые возвращают std::string, но не сдержали обещание возвращать std::string во всех цепочках кода.

PaulMcKenzie 12.01.2023 02:35
if (number >> 9 && number << 20) не делает того, что вы думаете, и поэтому teen_name не возвращает значение. Вы имели в виду > и < вместо этого?
Retired Ninja 12.01.2023 02:37

Как правило, ошибка сегментации является признаком того, что вы обращаетесь к недопустимому адресу памяти. (Здесь это не так очевидно, потому что у вас есть функции, которые не возвращают строку, а код, принадлежащий реализации строки, обращается к недопустимой «объектной» памяти объекта, которого там нет.)

Peter - Reinstate Monica 12.01.2023 02:40

И нельзя не подчеркнуть замечание @PaulMcKenzie в достаточной степени: всегда компилируйте с -Wall (или /W4 с MSVC), а также разбирайтесь и исправьте все предупреждения, прежде чем представлять код кому-либо (нам, вашему учителю, вашему работодателю, всему миру).

Peter - Reinstate Monica 12.01.2023 02:42

Кроме того, такие функции, как digit_name, можно записать в 4 строки кода, если вы просто использовали массив строк и немного математики.

PaulMcKenzie 12.01.2023 02:46

если число делится на 100, то будет напечатано digit_name, затем Hundred, а затем teens_name -- Если ваша программа должна преобразовывать число в слова, к сожалению, ваш код не делает этого правильно. Это гораздо больше, чем просто взять число и передать его teens_name и digit_name. Возьмем простой случай 300 — я не вижу, где вы печатаете слово «три», когда дается 300.

PaulMcKenzie 12.01.2023 02:57

«У меня есть несколько функций» — но только одна из них актуальна, когда возникает ошибка seg. Который из? Можете ли вы исключить большинство других функций? Имейте в виду, что ваш вопрос должен помочь другим. минимальный воспроизводимый пример лучше подходит для этой цели, чем программа, которая «распечатывает 1-999 в английском формате, используя слова».

JaMiT 12.01.2023 03:47

@PaulMcKenzie Спасибо за ваш комментарий. Как мне написать функцию digit_name в 4 строчки, объясните пожалуйста. И да, я забыл добавить #includ <string>

Krisha Patel 12.01.2023 14:44

@Peter - Восстановите Монику - я не знал, что могу проверить свой код и что с ним не так, используя -Wall (ow /W4). Это мой первый год изучения C++, и я новичок в программировании.

Krisha Patel 12.01.2023 14:45

@JaMiT Спасибо за комментарий. Я буду помнить, чтобы мой код был как можно меньше.

Krisha Patel 12.01.2023 14:46

@KrishaPatel - посмотрите ответ, который вы приняли. Все строки находятся в одном массиве, и вы используете небольшой расчет, чтобы получить правильную строку.

PaulMcKenzie 12.01.2023 14:49
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
11
88
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы не проверяете, действительно ли пользователь вводит number между 1..999. Таким образом, любое число за пределами этого диапазона приведет к сбою вашей логики.

Ваша функция define() объявлена ​​как возвращающая string (кстати, вам не хватает #include <string>), однако на самом деле она ничего return не делает. На самом деле, у большинства ваших функций та же проблема, поскольку они объявлены как возвращающие string, но не все пути их кода на самом деле ведут к оператору return. Это неопределенное поведение.

Кроме того, define() неправильно обрабатывает случаи, когда number >= 9. 9 полностью пропускается, и вы вообще не делите многозначные числа, вы просто передаете целое number как есть каждой функции, что затем приводит ваши функции к путям, в которых отсутствуют операторы return, вызывая неопределенное поведение повсюду место.

Кроме того, define() использует операторы битового сдвига >> и << во втором операторе if вместо использования операторов сравнения > и <. И он неправильно проверяет «делит на 10 равномерно» в своем 4-м операторе if, ему нужно будет использовать оператор модуля %, а не оператор деления /. Однако есть лучший способ написать свои if утверждения, не используя в них никакого деления.

С учетом сказанного попробуйте что-то еще вроде этого:

#include <iostream>
#include <string>
#include <limits>
using namespace std;

// defines 1 through 9 
string digit_name(int number){
  static const char* words[] = {
    "One ",
    "Two ",
    "Three ",
    "Four ",
    "Five ",
    "Six ",
    "Seven ",
    "Eight ",
    "Nine "
  };
  return words[number-1];
}

// defines 11 through 19
string teen_name(int number){
  static const char* words[] = {
    "Eleven ",
    "Twelve ",
    "Thirteen ",
    "Fourteen ",
    "Fifteen ",
    "Sixteen ",
    "Seventeen ",
    "Eighteen ",
    "Nineteen " 
  };
  return words[number-11];
}

// defines 10 through 90 (20, 30, 40 ... 90)
string tens_name (int number){
  static const char* words[] = {
    "Ten ",
    "Twenty ",
    "Thirty ",
    "Forty ",
    "Fifty ",
    "Sixty ",
    "Seventy ",
    "Eighty ",
    "Ninty "
  };
  return words[(number/10)-1];
}

// defines 100 through 900 (200, 300, 400 ... 900)
string hun_name (int number){
  return digit_name(number / 100) + "Hundred ";
}  

string define (int number){
  // defines what it will output based on the input of the user
  string result;
  
  // if number divides by 100, then it is one of the hundreds (ex: Two Hundred)
  if (number >= 100){
    result += hun_name(number);
    number %= 100;
  }
  
  // if number divides by 10...
  if (number >= 10){
    // if number is 11 through 19, output name (ex: Seventeen)
    if (number > 10 && number < 20){
      result += teen_name(number);
      number = 0;
    }
    else{
      // number is one of the tens (ex: Sixty)
      result += tens_name(number);
      number %= 10;
    }
  }
  
  // if number is 1 through 9, output the name (ex: One)
  if (number > 0){ 
    result += digit_name(number);
  }

  return result;
}

// main function - approved by Ms. B
int main() {
  int num;

  do{
    cout << "Please enter a number from 1 - 999: ";
    if (cin >> num){
      if ((num >= 1) && (num <= 999))
        break;
    }
    else{
      cin.clear();
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    cout << "Invalid input, try again!\n";
  }
  while (true);

  cout << define(num);
}

В качестве альтернативы вы можете заставить каждую функцию вычислять свою собственную часть оригинала number и выводить соответствующие слова, если они есть. Таким образом, define() может просто безоговорочно вызывать все функции, и будут возвращены только соответствующие слова, например:

#include <iostream>
#include <string>
#include <limits>
using namespace std;

// defines 1 through 9 
string digit_name(int number){
  static const char* words[] = {
    "One ",
    "Two ",
    "Three ",
    "Four ",
    "Five ",
    "Six ",
    "Seven ",
    "Eight ",
    "Nine "
  };
  // if number has 1 through 9, output the name (ex: One)
  number %= 10;
  if (number){
    return words[number-1];
  }
  return "";
}

// defines 11 through 19
string teen_name(int number){
  static const char* words[] = {
    "Eleven ",
    "Twelve ",
    "Thirteen ",
    "Fourteen ",
    "Fifteen ",
    "Sixteen ",
    "Seventeen ",
    "Eighteen ",
    "Nineteen " 
  };
  // if number has 11 through 19, output name (ex: Seventeen)
  number %= 100;
  if (number > 10 && number < 20){
    return words[number-11];
  }
  return "":
}

// defines 10 through 90 (20, 30, 40 ... 90)
string tens_name (int number){
  static const char* words[] = {
    "Ten ",
    "Twenty ",
    "Thirty ",
    "Forty ",
    "Fifty ",
    "Sixty ",
    "Seventy ",
    "Eighty ",
    "Ninty "
  };
  // if number divides by 10 and is not a teen, then it is one of the tens (ex: Sixty)
  number %= 100;
  if (number && (number < 11 || number > 19)){
    return words[(number/10)-1];
  }
  return "";
}

// defines 100 through 900 (200, 300, 400 ... 900)
string hun_name (int number){
  // if number divides by 100, then it is one of the hundreds (ex: Two Hundred)
  if (number >= 100) {
    return digit_name(number / 100) + "Hundred ";
  }
  return "";
}  

string define (int number){
  // defines what it will output based on the input of the user
  return hun_name(number) + tens_name(number) + teen_name(number) + digit_name(number);
}

// main function - approved by Ms. B
int main() {
  int num;

  do{
    cout << "Please enter a number from 1 - 999: ";
    if (cin >> num){
      if ((num >= 1) && (num <= 999))
        break;
    }
    else{
      cin.clear();
      cin.ignore(numeric_limits<streamsize>::max(), '\n');
    }
    cout << "Invalid input, try again!\n";
  }
  while (true);

  cout << define(num);
}

Этот код определенно работает, но я еще не научился этому. Мы не использовали статику в классе, поэтому я до сих пор понятия не имею, что делаю, но ваше объяснение значительно облегчает понимание того, что я сделал неправильно. Спасибо вам большое за это.

Krisha Patel 12.01.2023 14:47

Использование массивов (которые не обязательно должны быть статическими локальными, вместо этого они могут быть глобальными) просто делает функции более эффективными. Вместо этого вы можете так же легко вернуться к использованию операторов if. Суть в том, чтобы разбить пользовательский number на отдельные компоненты, а затем вывести соответствующие слова для каждого из них.

Remy Lebeau 12.01.2023 16:57

Я изменил свой код. Это то, что я получил сейчас:

#include <iostream>
#include <string>
using namespace std;

string digit_name(int digit) {
 // defines 1 through 9 
  if (digit == 1){
    return "One "; 
  }
  if (digit == 2){
    return "Two "; 
  }
  if (digit == 3){
    return "Three "; 
  }
  if (digit == 4){
    return "Four "; 
  }
  if (digit == 5){
    return "Five "; 
  }
  if (digit == 6){
    return "Six "; 
  }
  if (digit == 7){
    return "Seven "; 
  }
  if (digit == 8){
    return "Eight "; 
  }
  if (digit == 9){
    return "Nine"; 
  }
  return "";
}

string teen_name(int number){
  // defines 10 through 19
  if (number == 10){
    return "Ten "; 
  }
  if (number == 11){
    return "Eleven "; 
  }
  if (number == 12){
    return "Twelve "; 
  }
  if (number == 13){
    return "Thirteen "; 
  }
  if (number == 14){
    return "Fourteen"; 
  }
  if (number == 15){
    return "Fifteen"; 
  }
  if (number == 16){
    return "Sixteen"; 
  }
  if (number == 17){
    return "Seventeen"; 
  }
  if (number == 18){
    return "Eighteen"; 
  }
  if (number == 19){
    return "Nineteen"; 
  }
  return "";
}

string tens_name (int number){
  // defines 20 through 90 (20, 30, 40 ... 90)
  if (number >= 90){
    return "Ninety "; 
  }
  if (number >= 80){
    return "Eighty "; 
  }
  if (number >= 70){
    return "Seventy "; 
  }
  if (number >= 60){
    return "Sixty "; 
  }
  if (number >= 50){
    return "Fifty "; 
  }
  if (number >= 40){
    return "Forty "; 
  }
  if (number >= 30){
    return "Thirty "; 
  }
  if (number >= 20){
    return "Twenty "; 
  }
  return "";
}

// defines 100 through 900 (200, 300, 400 ... 900)
string hun_name (int number){
  return digit_name(number / 100) + "Hundred ";
}  

string define (int number){
  // defines what it will output based on the input of the user
  string result;
 
  // if number divides by 100, then it is one of the hundreds (ex: Two Hundred)
  if (number >= 100){
    result += hun_name(number);
    number %= 100;
  }

  // if number divides by 10...
  if (number >= 10){
    // if number is 11 through 19, output name (ex: Seventeen)
    if (number > 10 && number < 20){
      result += teen_name(number);
      number = 0;
    }
    else{
      // number is one of the tens (ex: Sixty)
      result += tens_name(number);
      number %= 10;
    }
  }

  // if number is 1 through 9, output the name (ex: One)
  if (number > 0){ 
    result += digit_name(number);
  }

  return result;
}

// main function - approved by Ms. B
int main() {
  int num;
  cout << "Please enter a number: ";
  cin >> num;
  cout << define (num) << endl;
  return 0;
}

Другие вопросы по теме