2015-12-04 3 views
1

Я создаю функцию, которая меняет строку и проверяет, является ли строка палиндром или нет. Когда я тестирую функцию с очевидным палиндром, например, «abba», функция говорит, что это не палиндром. Также прямая строка и обратная строка также отличаются длиной строки!C: Palindrome: Различные значения strlen

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

char forward [] = "abba"; //The string to be reversed 

int size = (sizeof(forward)/sizeof(forward[0]) - 1); 
int j = 0; 
char reverse [10]; 

void reverser(char forward []) { 

    printf("%s", "String forward: "); 
    for (int i = 0; i < size; i++) { //Function for printing out the forward string. 
     printf("%c", forward[i]); 
    } 

    printf("\n"); 

    printf("%s", "String reversed: "); 

    for (int i = size, j = 0; i >= 0; --i, ++j) { //Function for reversing the string and printing it. 
     reverse[j] = forward[i]; 
     printf("%c", reverse[j]);  
    } 

    printf("\n"); 

    if (strcmp(forward, reverse) != 0) { //Using strcmp to check if the forward and reversed string are the same. 
     printf("Not a palindrome!\n"); 
    } 
    else{ 
     printf("A palindrome!\n"); 
    } 

    printf("Forward string length: %d\n",strlen(forward)); 
    printf("Reversed string length: %d\n",strlen(reverse)); 
} 

int main() { 
    reverser(forward);  
} 

Выход:
Строка вперед: авва
Строка изменилась: ABBA
Не палиндром!
вперед Длина строки: 9
Перевернутой длина строки: 0

+0

Пожалуйста, отпечатай свой код правильно, я не могу его понять. –

+0

'int i = size' ->' int i = size-1' – BLUEPIXY

+0

Что это? Почему бы не strlen() здесь? int size = (sizeof (вперед)/sizeof (вперед [0]) - 1); –

ответ

1

В этом цикле

for (int i = size, j = 0; i >= 0; --i, ++j) { //Function for reversing the string and printing it. 
    reverse[j] = forward[i]; 
    printf("%c", reverse[j]);  
    } 

вперед [I] представляет собой завершение нуль строки, когда начальное значение переменной i равно size

Попробуйте следующую реализацию цикла

for (int i = size, j = 0; i != 0; ++j) { //Function for reversing the string and printing it. 
    reverse[j] = forward[--i]; 
    printf("%c", reverse[j]);  
    } 

Также учтите, что для var iables, который сохранит значения, возвращаемые оператором sizeof, или по функции strlen, лучше использовать тип size_t.

Таким образом, в этих утверждениях

printf("Forward string length: %d\n",strlen(forward)); 
printf("Reversed string length: %d\n",strlen(reverse)); 

использование спецификатора формата %zu вместо %d

Например

printf("Forward string length: %zu\n",strlen(forward)); 
printf("Reversed string length: %zu\n",strlen(reverse)); 

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

+1

Также обратите внимание, что 'reverse' не завершается нулем. – chqrlie

+0

@chqrlie Почему вы так решили ? –

+0

Потому что, даже если это не является строго необходимым, потому что 'reverse' является глобальной переменной и операция выполняется только один раз, я считаю, что OP не что его код не может использоваться более общим образом. – chqrlie

0

Я думаю, что первый символ из "обратных" является '\ 0'.

Заменить эту строку int size = (sizeof(forward)/sizeof(forward[0]) - 1); на int size = strlen(forward).

Кроме того:

printf("%s", "String forward: "); for (int i = 0; i < size; i++) { //Function for printing out the forward string. printf("%c", forward[i]); }

можно заменить printf("String forward : %s\n", forward);

0

Вы ставите нулевой символ в первом индексе при движении задним ходом (reverse[0]). Вот почему каждый терпит неудачу.

for (int i = size, j = 0; i >= 0; --i, ++j) {   
    reverse[j] = forward[i]; 
} 

должно быть

for (int i = size - 1, j = 0; i >= 0; --i, ++j) { 
    reverse[j] = forward[i]; 
} 
reverse[size] = '\0'; 

sizeof(forward)/sizeof(forward[0]) 5, что означает size = 4.

forward[0] = 'a' 
forward[1] = 'b' 
forward[2] = 'b' 
forward[3] = 'a' 
forward[4] = '\0' 
0

Реверсивный код выключен один на один из индексов, i должен работать от size-1 до 0 включительно:

// Function for reversing the string. 
for (int i = size, j = 0; i > 0;) { 
    reverse[j++] = forward[--i]; 
} 
reverse[size] = '\0'; 

Чтобы избежать обновления 2 различных индексов, вы можете упростить этот цикл:

// Function for reversing the string. 
for (int i = 0; i < size; i++) { 
    reverse[i] = forward[size - 1 - i]; 
} 
reverse[size] = '\0'; 

Есть много других вопросов, в вашем коде:

  • forward и size глобальные переменные, но вы также имя аргумента в функции reverser таким же образом и использовать глобальный size там, что может быть неприемлемым, если вызывается с другим аргументом. size и даже хуже j не должны быть глобальными переменными

  • имя функции reverser несовместимо с тем, что делает эта функция (!): Печать аргумент.

  • вы можете напечатать строку аргументов напрямую с помощью формата печати %s. Нет необходимости в цикле.

  • %d - неправильный формат для strlen() возвращаемое значение. Либо введите (int)strlen(forward), либо используйте %zu.

+0

Вы должны сделать код более понятным, удалив 'j ++' и '--i 'из этих скобок и поместить их в нужное место в for-loop – smac89

+0

@ Smac89: я поставил их там специально. Нисходящие циклы не должны использовать'> = 0', потому что этот тест неуместен для неподписанных переменных. индекс при использовании или пост-укорачивании его в тестовом выражении является идиоматичным, хотя и запутанным для новичков. Предлагаемая альтернатива проще и меньше подвержена ошибкам. – chqrlie