Программа на палиндроме, работающая на локальном ПК, но не на INGInious - PullRequest
0 голосов
/ 27 февраля 2019

У меня есть программа переменного тока, которая обнаруживает палиндром.Он также обнаруживает палиндромы с пробелами.Возвращает -1, если строка равна нулю, 1, если это палиндром, и 0 в противном случае.Вот код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int pal(char *str){

    if(str[0] == '\0'){
        return -1;
    }else{
        size_t i = 0;
        size_t j = strlen(str) - 1;
        while(*(str + i) != '\0'){
            if(*(str + i) == ' '){
                i++;
                continue;
            }else if(*(str + j) == ' '){
                j--;
                continue;
            }else{
                if(*(str + i) != *(str + j)){
                    return 0;
                }
            }
            i++;
            j--;
        }

        return 1;

    }

}


int main(){

    char *str = "a man a plan a canal panama";
    printf("%d", pal(str));
    printf("\n");
    return 0;
}

Когда я скомпилировал и запустил эту программу на своем локальном компьютере, она работала нормально.Но когда я загрузил его в INGInious вопрос моего курса CS (INGInious - это платформа, на которой люди могут загрузить свои ответы по определенной теме, а система просматривает их), это вызывает ошибку сегментации.Есть ли сценарий, который может привести к SegFault, который я не знаю?

Ответы [ 3 ]

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

Как я уже говорил в моих комментариях, вы не контролируете значение j, и из-за этого ваш код потенциально может демонстрировать неопределенное поведение - когда j становится 0, но вы продолжаете уменьшать его,оно оборачивается и становится максимальным значением типа size_t (довольно впечатляющее число на современной платформе).

Этого не происходит с предоставленной вами строкой, но, я думаю, ваша платформа тестирования тестирует ее на другой строке(это единственное объяснение сбоя, которое у меня есть).

Например, ваш код будет подвержен неопределенному поведению в следующей строке: "a bcd"

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

Ваш код слишком сложен.

#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>

bool is_palindrome(char const *str)
{
    size_t length = strlen(str);

    for (char const *front = str, *back = str + length - 1; front != back; ++front, --back) {
        while (isspace((char unsigned) *front) && front != str + length - 1)
            ++front;

        while (isspace((char unsigned) *back) && back != str)
            --back;

        if (front == back)
            break;

        if (*front != *back)
            return false;
    }
    return true;
}

int main(void)
{
    char const *foo = "a man a plan a canal panama";
    printf("%d\n", is_palindrome(foo));

    char const *bar = "hello";
    printf("%d\n", is_palindrome(bar));
}

Вывод:

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

В цикле ниже:

while(*(str + i) != '\0'){
    if(*(str + i) == ' '){
        i++;
        continue;
    }else if(*(str + j) == ' '){
        j--;
        continue;
    }else{
        if(*(str + i) != *(str + j)){
            return 0;
        }
    }
    i++;
    j--;
}

Когда *(str + i) == '\0', это должно быть i == strlen(str) и j == -1 (если в строке нет пробела. В противном случае я не уверен), и это можетбыть проблемой.Но опять же, я не могу видеть, что вы не получите доступ к str вне диапазона.Вместо этого я бы предложил сделать это, чтобы в вашем цикле было легче увидеть завершающее условие:

while(i < j){
    // ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...