首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何有效地解决C中的off-by-one错误?

如何有效地解决C中的off-by-one错误?
EN

Stack Overflow用户
提问于 2019-06-01 15:20:42
回答 1查看 59关注 0票数 0

我已经编写了一个程序来反转char数组,也可以反转该数组中的单词。该程序几乎可以正常工作,但我认为这是一个错误。我已经尝试过处理与循环计数器相关的数学问题,但还没能解决这个问题。我可以使用什么工具或技术来解决这类问题?我已经尝试了printf语句,还使用了gdb,并对计数器变量进行了监视。

代码语言:javascript
复制
#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。很明显,这是一个off-by-one错误,但我花了一些时间在这个问题上,并在其他程序中遇到了类似的C错误。

EN

回答 1

Stack Overflow用户

发布于 2019-06-01 15:38:12

错误存在于reverse_words中。有时tail索引单词最后一个字符之后的字符,有时tail索引单词本身的最后一个字符。

reverse_wordsreverse_array的调用是:

代码语言:javascript
复制
reverse_arr(&arr[start], tail - start);

如果start对单词的第一个字符进行索引,并且单词中包含tail - start字符,则此方法有效。因此,tail必须索引单词最后一个字符之后的字符。

条件arr[tail] == ' '与此一致,但结束条件不是:(1)循环太快退出,(2)测试tail == len-1也关闭1。

这可以通过再次迭代,并在尝试访问arr[tail]之前检查end条件来解决(以避免索引超过end):

代码语言:javascript
复制
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;
        }
    }
}

注意,循环退出条件现在是<=而不是<,循环内结束测试已经移动了一位,并且循环内检查的顺序颠倒了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56404682

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档