Как я могу эффективно устранить отдельные ошибки в C? - PullRequest
0 голосов
/ 01 июня 2019

Я написал программу для обращения к массиву символов, а также для обращения слов в этом массиве. Программа почти работает так, как задумано, но я считаю, что это ошибка. Я пробовал возиться с математикой, включающей счетчики циклов, но не смог понять это. Какой инструмент или методы я могу использовать для решения этого типа проблемы? Я пробовал операторы printf, а также использовал gdb и помещал часы в переменные счетчика.

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

void reverse_arr(char *arr, size_t len);
void print_chars(char *arr, size_t len);
void reverse_words(char *arr, size_t len);
int main(int argc, char **argv)
{
    char phrase[] = {'p','e','r','f','e','c','t',' ',
                    'm','a','k','e','s',' ','p','r',
                    'a','c','t','i','c','e'};

        size_t i;

    reverse_arr(phrase, sizeof(phrase));
    reverse_words(phrase,sizeof(phrase));
    print_chars(phrase, sizeof(phrase));

    return EXIT_SUCCESS;
}

void reverse_arr(char *arr, size_t len)
{
    size_t front, tail;
    tail = len-1;
    char tmp;
    for(front = 0; front < len/2; front++, tail--)
    {
        tmp = arr[front];
        arr[front] = arr[tail];
        arr[tail] = tmp;
    }

    return;
}

// 1. Search for a space
// 2. When space is found, that space is the place to stop and indicates all between the start and it are a word
// 3. Now call reverse_arr on the word and calculate the length of the word by subtracting tail - start
// 
void reverse_words(char *arr, size_t len)
{
    size_t tail, start;
    for(tail = start = 0; tail < len; tail++)
    {
        if(arr[tail] == ' ' || tail == len-1)
        {
            reverse_arr(&arr[start], tail - start);
            start = tail+1;
        }
    }
}

void print_chars(char *arr, size_t len)
{
    size_t i;
    for(i = 0; i < len; i++)
    {
        putchar(arr[i]);
    }
    putchar('\n');

    return;
}

Этот код возвращает practice makes erfectp. Ясно, что это ошибка, но я потратил некоторое время на это и перенес подобные ошибки в C в других программах.

1 Ответ

1 голос
/ 01 июня 2019

Ошибка в reverse_words.Иногда tail индексирует символ после последнего символа слова, а иногда tail индексирует последний символ самого слова.

Вызов reverse_array из reverse_words is:

reverse_arr(&arr[start], tail - start);

Это работает, если start индексирует первый символ слова и если в слове есть tail - start символов.Поэтому tail должен индексировать символ после последнего символа слова.

Условие arr[tail] == ' ' согласуется с этим, но условие завершения не является: (1) цикл завершаетсяслишком рано, и (2) тест tail == len-1 также отключен на единицу.

Это можно исправить, повторив еще раз и проверив условие завершения перед попыткой доступа arr[tail] (чтобы избежать индексации после конца):

void reverse_words(char *arr, size_t len)
{
    size_t tail, start;
    for (tail = start = 0; tail <= len; tail++)
    {
        if (tail == len || arr[tail] == ' ')
        {
            reverse_arr(&arr[start], tail - start);
            start = tail+1;
        }
    }
}

Обратите внимание, что условие выхода из цикла теперь равно <=, а не <, проверка конца цикла смещена на единицу, ипорядок проверок внутри цикла обратный.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...