Занялся на досуге изучением языка си по книжке K&R. Дошёл до задания 1.19. По итогу выполнения решил написать данное сообщение, как памятку себе.
Итак, программа выглядит следующим образом:
/* программа, реверсирующая входные строки */
#include <stdio.h>
#define MAXLINE 1000
void reverse(char s[]);
int my_getline(char s[], int);
int main()
{
int len;
char line[MAXLINE];
while((len = my_getline(line, MAXLINE)) > 0) {
printf("Исходная строка выглядит так: %s", line);
reverse(line);
printf("Реверсированная строка выглядит так: %s", line);
}
return 0;
}
int my_getline(char s[], int lim)
{
int i, c;
for(i = 0; i < lim -1 && (c = getchar()) != EOF && c != '\n'; ++i) {
s[i] = c;
}
if(c == '\n') {
s[i] = c;
++i;
}
s[i] = '\0';
return i;
}
/* функция reverse: переписывает строки в обратном порядке. Суть работы в следующем:
т.к. мы знаем, что любая строка заканчивается символом '\0', можно на время удалить
из строки данный символ и занять его место первым элементом массива. После этого можно
осуществить последовательный перенос всех элементов. В последствии необходимо будет
"сдвинуть" полученную строку влево */
void reverse(char s[])
{
int n, i, c, j;
c = n = 0;
while(s[n] != '\0') {
++n;
}
if(s[n-1] == '\n') {
c = s[n-1]; //c теперь содержит символ перехода на новую строку
n = n - 2; //не будем подставлять в качестве первого символа переход на новую строку
}
/* выясняем, какое у нас число символов в строке: чётное или нечётное */
if((n%2) == 0) {
j = n/2;
} else {
j = n/2 + 1;
}
/* переносим крайние элементы в массиве */
s[n+1] = s[0];
s[0] = s[n];
/* переносим остальные элементы */
for(i = 0; i < j; ++i) {
s[i] = s[n-i];
s[n-i] = s[i+1];
}
/* нужно "сдвинуть" символы влево, начиная с середины */
for(i = j; i < n + 1; ++i) {
s[i] = s[i+1];
}
if(c == '\n') {
n = n + 1;
s[n] = '\n';
}
s[n+1] = '\0';
}