Продолжайте получать ошибки во время выполнения для простой программы на C - PullRequest
0 голосов
/ 27 мая 2018

Мне нужно написать программу, которая проверяет, является ли строка палиндромом или нет.Палиндром - это последовательность, которая одинакова вперед и назад.Например, каяк - это палиндром, каноэ - не палиндром, Ханна - палиндром и т. Д.

Вот мой код:

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

#define MAX_CHAR 4096

int main(void) {

    printf("Enter a string: ");

    char line[MAX_CHAR] = {0};

    fgets(line, MAX_CHAR, stdin);

    int length = strlen(line) - 1;

    int i = 0;
    int j = length - 1;

    char line2[length];
    while (i < length){
        if (j >= 0){
            line2[i] = line[j];
        }
        i++;
        j--;
    }

    if (strcmp(line, line2) != 0){
        printf("String is not a palindrome\n");
    } else if (strcmp(line, line2) == 0) {
        printf("String is a palindrome\n");
    }

    return 0;
}

Это работает для непалиндромов, нокаждый раз, когда я тестирую с палиндромом, я получаю ошибку во время выполнения, как показано на изображении .Как мне это решить?

Ответы [ 3 ]

0 голосов
/ 27 мая 2018

У вас неправильная проверка границ, а также fgets читает новую строку, которую вы должны удалить.Это единственный конкурирующий ответ, который также проверяет, не является ли введенная строка не пустой:

#include <string.h>

#define MAX_CHAR 4096

int main(void) {

    printf("Enter a string: ");

    char line[MAX_CHAR] = {0};

    fgets(line, MAX_CHAR, stdin);
    //remove new line
    int length = strlen(line);
    if (length > 0) {
        line[length-1] = '\0';
    }

    //update length
    length = strlen(line);
    if (!length) {
        printf("String is empty\n");
        return 1;
    }

    int i = 0;
    int j = length - 1;

    char line2[length+1];

    while (i < length){
        line2[i++] = line[j--];
    }

    //Add 0 char
    line2[i] = '\0';
    if (strcmp(line, line2) != 0){
        printf("String is not a palindrome\n");
    } else if (strcmp(line, line2) == 0) {
        printf("String is a palindrome\n");
    }


  return 0;
}
0 голосов
/ 27 мая 2018

Проблема, с которой вы столкнулись, вызвана тем, что вы не добавляете нулевой терминатор в line2 (а в массиве также не хватает места для него), поэтому line2 не является нулевым символом в концестрока байтов.

Передача указателя на что-либо кроме строки байтов с нулем в конце на strcmp вызывает неопределенное поведение

Самый простой способ исправитьКод предназначен для внесения следующих изменений:

/* Don't subtract 1 from `strlen`, otherwise you don't copy the entire string in your loop */
int length = strlen(line);
/* Unchanged */
int i = 0;
int j = length - 1;
/* increase size of array by 1 to have space for null-terminator */
char line2[length + 1];
/* Loop is unchanged */
while (i < length){
    if (j >= 0){
        line2[i] = line[j];
    }
    i++;
    j--;
}
/* Add null-terminator to have a valid byte string */
line2[length] = '\0'; 

Обратите также внимание, что существуют более простые способы выполнить проверку палиндрома, но этот ответ сфокусирован только на том, почему ваш код сталкивается с ошибкой времени выполнения.

РЕДАКТИРОВАТЬ: Как указано в комментариях fgets также хранит символ новой строки внутри массива.Чтобы проверка вашего палиндрома работала корректно, вам необходимо настроить код (например: удалить символ новой строки из line перед созданием line2 и скопировать символы)

0 голосов
/ 27 мая 2018

Проще:

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

int palindrome(const char *word)
{
    size_t len = strlen(word);  
    const char *end = word + len -1;
    len >>= 1;
    while(len--)
    {
        if(*word++ != *end--)
            return 1;  //not
    }
    return 0; //yes;
}

int main()
{
printf("%s\n", palindrome("kayak") ? "No" : "Yes");

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...