Преобразовать строку, изменив порядок следования слов в строке на обратный - C (СИ) (71348)
Формулировка задачи:
Помогите пожалуйста, преобразовать строку, изменив порядок следования слов в строке на обратный.Функциями, объявленными в string.h не пользоваться. Я тут набросал программу, но она выводит не то что надо, к примеру строка: hello world, он выведет вместо world hello - dlrow olleh. Как её доработать, чтобы она работала правильно?
#include <stdio.h>
#include <locale.h.>
void reverse(char str[], int n)
{
int c, i, j;
for (i=0, j=n-1; i<j; i++, j--) {
c=str[i];
str[i]=str[j];
str[j]=c;
}
}
main ()
{
char str[50];
int i, l=0;
setlocale(LC_ALL, "Rus");
printf ("Введите строку\n");
gets (str);
i=0;
while (str[i] !='\0') {
++l;
++i;
}
reverse(str, l);
printf ("Строка в обратном порядке\n");
printf ("%s",str);
}Решение задачи: «Преобразовать строку, изменив порядок следования слов в строке на обратный»
textual
Листинг программы
#include <stdio.h>
#include <ctype.h>
#define ch_chg(t, a, b) \
(t) = (a);\
(a) = (b);\
(b) = (t);
char* rev_words(char* s){
int m, i;
char* p, *e, c, *q, *t = s;
e = s;
while(*e)
++e;
if(e > s)
for(--e; (e > t) && isspace(*e); --e);
while(*s && (s < e)){
while(isspace(*s))
++s;
q = s;
while(*q && !isspace(*q))
++q;
m = (int)(q - s);
for(i = 0; i < m; ++i){
for(p = s; p < e; ++p){
ch_chg(c, *p, *(p + 1));
}
}
e -= m;
if(*s){
for(p = s; p < e; ++p){
ch_chg(c, *p, *(p + 1));
}
--e;
}
}
return t;
}
int main(void){
char s1[] = "ADA APL Algol Cobol Fortran";
char s2[] = "Кедр Сосна Ель Пихта Лиственница";
puts(s1);
puts( rev_words(s1) );
putchar('\n');
puts(s2);
puts( rev_words(s2) );
return 0;
}
Объяснение кода листинга программы
- Включаются необходимые заголовочные файлы для работы со строками и преобразования символов.
- Определяется функция
rev_words, которая будет выполнять задачу. - Внутри функции объявляются необходимые переменные:
int m, i;- для хранения индексов и количества слов в строке;char* p, *e, c, *q, *t = s;- для работы с указателями на символы строки.
- Инициализируется указатель
eна последний символ строкиs. - Переменная
sкопируется вt, чтобы не изменять исходную строку. - Переменная
eустанавливается на позицию после последнего символа строкиs. - В цикле, пока есть символы в строке
s, происходит следующее:- Пропускаются пробелы в начале слова.
- Сохраняется текущий символ
cи его следующий символ(p = s; p < e; ++p)для дальнейшей обработки. - Устанавливается переменная
qна позицию начала слова, аpна позицию после последнего символа слова. - Вычисляется длина слова
mи сохраняется в переменнойi. - В цикле
iраз, начиная с первого символа после пробела, происходит обмен символовcи(p + 1). - Указатель
eсдвигается наmсимволов назад. - Если текущий символ
sне является пробелом, то происходит обмен символовcи(p + 1). - Если текущий символ
sявляется последним символом слова, то происходит обмен символовcи(p + 1).
- В конце функции возвращается указатель на начало строки
t. - В функции
mainсоздаются две строкиs1иs2для тестирования функцииrev_words. - Выводится исходная строка
s1. - Выводится строка
rev_words(s1). - Выводится символ новой строки.
- Выводится исходная строка
s2. - Выводится строка
rev_words(s2). - Функция
mainвозвращает 0, что означает успешное выполнение программы.