CS50 Неделя 2 Цезарь

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

код, который я пробовал

#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
bool only_int(string inputkey);
int check(string inputkey);
int main(int argc , string argv[])
{
    bool check = only_int(argv[1]);
   if (argc == 2)
   {
    if (check == true)
    {
        string plaintext = get_string("plaintext : ");
        return 0;
    }
    else
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
   }
    else if ((argc != 2) || (argv[1] == NULL))
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
}

//functions to check for only integral input
bool only_int(string inputkey)
{
    int y = check(inputkey);
    if (y > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}
int check(string inputkey)
{
int result = 0;
    for(int i = 0 , l = strlen(inputkey) ; i < l ; i++)
    {
        int x = isdigit(inputkey[i]);
        if (x > 0)
        {
            result++;
        }
    }
return result;
}

я ожидал, что это будет что-то вроде этого

$ ./caesar                                                                                          
Usage: ./caesar key                                                                                 
$ ./caesar HELLO                                                                                    
Usage: ./caesar key                                                                                 
$ ./caesar 1 2 3                                                                                    
Usage: ./caesar key                                                                                 
$ ./caesar 13                                                                                       
plaintext:  

но что я получил

                                                                              
$ ./caesar HELLO                                                                                    
Usage: ./caesar key                                                                                 
$ ./caesar 1 2 3                                                                                    
Usage: ./caesar key
$ ./caesar 
Segmentation fault (core dumped)                                                                                 
$ ./caesar 13                                                                                       
plaintext: 

Первая строка кода вашего приложения — bool check = only_int(argv[1]);. Но если argv[1] не существует, ваш код выйдет из строя или сделает что-то неопределенное. Вы всегда должны проверять, больше ли argc, чем 1, прежде чем проверять что-либо еще.

OldBoy 29.06.2024 10:09

@OldBoy только что проверил, все работает нормально, спасибо!

Manasvi Sharma 29.06.2024 10:12
Meta.stackoverflow.com/questions/285551/…
Marek R 29.06.2024 10:13

@ManasviSharma Какого результата вы ожидаете от таких вызовов, как ./caesar abc3 или ./caesar 0?

chux - Reinstate Monica 29.06.2024 12:08

@chux-ReinstateMonica для первого следует просто показать «Использование: ./caesar key» и принять 0 в качестве допустимого значения. Я понял, что первый вариант не работает, и исправил это сейчас, спасибо, что обратили мое внимание на эту вещь!

Manasvi Sharma 30.06.2024 07:24

Обратите внимание, что if (x > 0) является неправильным тестом после int x = isdigit(inputkey[i]);, поскольку важный результат isdigit() равен нулю или ненулевому значению. Протестируйте лучше как if (x) или пропустите x задание и протестируйте if (isdigit(inputkey[i])).

chux - Reinstate Monica 30.06.2024 16:38

@chux-ReinstateMonica, я так и сделал, теперь все исправлено :)

Manasvi Sharma 02.07.2024 05:10
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
7
73
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Вы получаете доступ к argv[1] перед проверкой длины argv, что означает, что вы можете получить доступ к памяти, которой вы не владеете. Поменяйте местами проверки, и все будет в порядке:

int main(int argc , string argv[])
{
    if (argc != 2) 
    {
        printf("Usage: ./caesar key\n");
        return 1;
    }
    // Now you know you have the right number of arguments, 
    // and can safely access argv[1] and check it

это сработало для меня, спасибо!

Manasvi Sharma 02.07.2024 05:10

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