функция для реверсирования массива в C (K&R 2-е изд.)
Попытка выполнить упражнение 1-19 из K&R 2-го изд., например, написание функции для реверса строки. Я думал, что справился, но вывод на печать выглядит странно : -) если я использую STRINGSIZE 5, вывод будет
Original String: hello
Reversed String: ollehhello. Если я использую STRINGSIZE 6, чтобы иметь в виду символ конца строки '' и изменить цикл while на while ((outputString[STRINGSIZE - (i + 2)] = inputString[i]) != ''), то я получаю Original String: hello
Reversed String: olleh?hello, я предполагаю, что ?-это какой-то случайный символ, идущий от '', добавленного к обратной строке в цикле while в позиции 5; но hello снова добавляется. Может ли кто-нибудь объяснить, как это произошло hello добавляется в конец olleh , и как я могу избавиться от него, чтобы получить только правильную перевернутую строку ?
Вот код:
#include <stdio.h>
#define STRINGSIZE 5
void reverseString (char inputString[], char outputString[]);
int main(void) {
char stringToReverse[] = "hello";
char reversedString[STRINGSIZE];
reverseString(stringToReverse, reversedString);
printf("Original String: %snReversed String: %sn", stringToReverse, reversedString);
}
void reverseString (char inputString[], char outputString[]) {
int i;
i = 0;
while ((outputString[STRINGSIZE - (i + 1)] = inputString[i]) != '')
++i;
}
2 ответа:
Сначала я предлагаю вам изменить эту строку:
char reversedString[STRINGSIZE];К
char reversedString[strlen(stringToReverse) + 1]; // + 1 to make room for the string terminationТогда я бы сделал что-то вроде:
void reverseString (char inputString[], char outputString[]) { int i; int len = strlen(inputString); for(i=0; i<len; ++i) { outputString[len-i-1] = inputString[i]; } outputString[len] = '\0'; // Terminate the string }
Во-первых, в символьном массиве
reversedString[]недостаточно места для хранения нулевого термина строки"hello". Один из вариантов-использовать массив переменной длины здесь:Власы были введены в C99 и стали необязательными в C11. Насколько я помню, K&R не включает покрытие массивов переменной длины, так как даже 2-е издание было опубликовано до этого.char reversedString[strlen(stringToReverse) + 1];Другой вариант, который был бы совместим с C89, заключается в использовании оператора
sizeof:char stringToReverse[] = "hello"; char reversedString[sizeof stringToReverse];Здесь результат от оператора
sizeofизвестен во время компиляции и может быть использован при объявлении массива фиксированного размера. Этот размер включает в себя пространство для нулевого Терминатора, в отличие от результата изstrlen("hello"). Обратите внимание, что это не будет работать сchar *stringToReverse = "hello";, так как тогда операторsizeofбудет давать размер указателя. Это также не сработало бы, если быstringToReverseбыл передан в функцию первым, так как тогда имя массива распалось бы на указатель на первый элемент функции.stringToReverse.В функции
reverseString()необходимо определить длинуinputString(ПосколькуSTRINGSIZEбольше не используется); это можно сделать с помощьюstrlen()или в цикле. Затем, критически важно, функция должна обязательно добавить нулевой Терминатор (\0) кoutputString[]перед возвращением. Также обратите внимание, что операторreturnбыл добавлен в конецmain(), чтобы сделать это действительно совместимым с C89:#include <stdio.h> void reverseString (char inputString[], char outputString[]); int main(void) { char stringToReverse[] = "hello"; char reversedString[sizeof stringToReverse]; reverseString(stringToReverse, reversedString); printf("Original String: %s\nReversed String: %s\n", stringToReverse, reversedString); return 0; } void reverseString(char inputString[], char outputString[]) { int length = 0; int i = 0; /* Get inputString length; or use strlen() */ while (inputString[length] != '\0') { ++length; } /* Copy to outputString[] in reverse */ while (i < length) { outputString[i] = inputString[(length - i) - 1]; ++i; } /* Add null terminator */ outputString[i] = '\0'; }