У вас есть ряд проблем, но ваша основная проблема в вашем обращении. Вы пытаетесь повернуть вспять с помощью:
h=strlen(s)-1;
if(h>=1&&h<=100000){
for(i=0,j=h;i<=h&&j>=0; j--,i++) {
b[i]=s[j];
}
Это не удастся для strlen(s) == 1
, не гарантирует нулевое завершение, и поскольку вы используете h=strlen(s)-1;
, ваше h
в if (h % 2 == 0)
приведет к противоположному определению EVEN
и ODD
. Вместо этого вам нужно:
#define MAXC 100000 /* if you need a constant, #define one (or more) */
...
h = strlen (s); /* h must be strlen(s) - not - 1 */
if (h >= 1 && h < MAXC) { /* now loop j=h-1; j < h times */
for (i = 0, j = h-1; i < h && j >= 0; j--,i++)
b[i] = s[j];
b[i] = 0; /* and ensure b is nul-terminated */
( примечание: код с достаточным интервалом намного легче читать и отлаживать)
Далее вам не удается проверить возвращение каждого вызова на scanf
, вместо этого вслепую используя переменные без указания того, был ли ваш ввод успешным - рецепт для Неопределенное поведение . Вы должны проверить КАЖДЫЙ пользовательский ввод, например,
if (scanf ("%d", &n) != 1 || n > 50) {
fputs ("error: invalid integer or out-of-range.\n", stderr);
return 1;
}
while (n-- && scanf ("%s", s) == 1) {
Простой выбор логического факторинга вашего кода полностью исключает необходимость в переменных t
и d
. Обратите внимание, что ваши условия для n
: (1) он действителен, и (2) он 50
или меньше. Они могут быть объединены в одну проверку. То же самое относится к циклу n
раз при чтении слов в s
.
При внесении этих изменений ваш код упрощается до:
#include <stdio.h>
#define MAXC 100000 /* if you need a constant, #define one (or more) */
int main (void)
{
char s[MAXC];
int n;
if (scanf ("%d", &n) != 1 || n > 50) {
fputs ("error: invalid integer or out-of-range.\n", stderr);
return 1;
}
while (n-- && scanf ("%s", s) == 1) {
char b[MAXC]; /* b is only needed within loop */
int h = strlen (s), i = 0, j; /* as are h, i, j, no - 1 for h */
if (h >= 1 && h < MAXC) { /* now loop j=h-1; j < h times */
for (i = 0, j = h-1; i < h && j >= 0; j--,i++)
b[i] = s[j];
b[i] = 0; /* and ensure b is nul-terminated */
if (strcmp (s, b) == 0) {
if (h % 2 == 0)
printf ("YES EVEN\n");
else
printf ("YES ODD\n");
}
else
printf ("NO\n");
}
}
return 0;
}
, который теперь обеспечивает проверку палиндрома и длину ODD
или EVEN
, которую вы искали, например,
Пример использования / Вывод
$ echo "5 abcba abccba abcdba a aa" | ./bin/pdromerefmt
YES ODD
YES EVEN
NO
YES ODD
YES EVEN
Необходимо дополнительно защитить границы массива s
, добавив модификатор field-width для преобразования "%s"
, например. "%99999s"
, что устраняет необходимость проверять h <= 100000
(что уже вызвало бы Неопределенное поведение , если ввод был 100000
символов или больше). Нет необходимости проверять h >= 1
, поскольку ограничения цикла ничего не делают с h = 0
- но гарантируют пустую строку.
Благодаря дополнительным настройкам и защите границ массива ваш цикл упрощается до:
while (n-- && scanf ("%99999s", s) == 1) {
char b[MAXC]; /* b is only needed within loop */
int h = strlen(s), i = 0, j = h;/* as are h, i, j, no -1 for h */
while (j--) /* must loop j times, regardless */
b[i++] = s[j]; /* reversing characters in s in b */
b[i] = 0; /* and ensure b is nul-terminated */
if (strcmp (s, b) == 0) {
if (h % 2 == 0)
printf ("YES EVEN\n");
else
printf ("YES ODD\n");
}
else
printf ("NO\n");
}