четверг, июня 14, 2012

K&R Язык программирования C. Упражнение 1.19. Напишите функцию reverse(s), которая переписывает свой строковый аргумент в обратном порядке

Занялся на досуге изучением языка си по книжке 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';
}