【问题标题】:Why is my function representation not reverse-copying data?为什么我的函数表示不是反向复制数据?
【发布时间】:2014-11-07 06:29:42
【问题描述】:

我有 fwrite 的这个函数表示,它向后写入字节。但是.. 它并没有真正将它们向后复制,这似乎很奇怪。

size_t fwrite_backward ( const void * ptr, size_t size, size_t count, FILE * stream )
{
    int i, chr;

    for(i = count * size; i != 0; i--)
    {
        if( fputc(*(unsigned char*)ptr + (count * size) - i, stream) != EOF )
        chr++;
    }
    return chr;
}

它的行为应该与 fwrite 完全相同,但有两个不同之处:

  • 它向后复制数据
  • 没有设置ferror

我可能做错了什么?

【问题讨论】:

  • 提示:尝试在您的头脑中或使用调试器单步执行您的代码。在循环的第一次迭代中i 的值是多少?第一次迭代写入的第一个字节的索引是多少?
  • 你没有初始化chr(大概应该设置为零)。但是,这不是主要问题。
  • 哦,循环实际上是反转的..是的..我忘了初始化chr谢谢..
  • 是的,您有两种方法可以同时反转正在使用的数据的顺序,这意味着一种抵消另一种。
  • 您还传递了一个指向 fputc 的指针,您应该在其中传递一个值。

标签: c io fwrite


【解决方案1】:

下面的实现似乎有效。它还纠正了您的版本的一些小设计缺陷:

  • 您的代码将所有 bytes 向后写出,但您应该将所有 items 向后写出,并按照项目本身中的字节按原始顺序。 (毕竟,sizecount 之间有什么区别?)下面的代码适用于任何大小的项目。

  • Yor 代码返回写入的字节数。但是fwrite返回的是写入的项目数。

  • 循环在写入不成功时提前结束。

所以:

size_t fwrite_rev(const void *ptr, size_t size, size_t count, FILE *stream)
{
    const unsigned char *p = ptr;
    size_t written = 0;

    while (count--) {
        if (fwrite(p + size * count, size, 1, stream) < 1) break;
        written++;
    }

    return written;
}

【讨论】:

    【解决方案2】:

    用于获取fputc 字节的索引错误。此外,您不正确地取消引用指针。

    表达式*(unsigned char*)ptr + (count * size) - i 等价于:

     char c = *(unsigned char*)ptr, (c + count*size - i)
    

    这绝对不是你想要的。

    代替

        if( fputc(*(unsigned char*)ptr + (count * size) - i, stream) != EOF )
    

    应该是

        if( fputc(*((unsigned char*)ptr + i - 1), stream) != EOF )
    

        if( fputc(((unsigned char*)ptr)[i - 1], stream) != EOF )
    

    【讨论】:

    • 应该是((unsigned char *)ptr)[i - 1],因为fputc需要一个值,而不是一个指针。
    • 结果仍然是正确的顺序,没有颠倒。
    • 不知道,C89,char arr[3] = { '3', '2', '1' }; 反转并且它起作用了。谢谢。
    • @Corelation:您需要for (int i = 0; i &lt; count * size; i++) fputc(((unsigned char *)ptr)[count * size - i - 1], stream);for (int i = count * size; i &gt; 0; i--) fputc(((unsigned char *)ptr)[i], stream);,但您不应该同时倒计时并从字符串的末尾开始操作,就像您目前正在做的那样(尝试做)。我还会在循环之外设置一次指针,并且与循环限制表达式类似,因此循环的主体更易于理解。这些演员表使其难以阅读。
    猜你喜欢
    • 2021-08-18
    • 2012-11-18
    • 1970-01-01
    • 2011-05-12
    • 1970-01-01
    • 2019-03-02
    • 2018-11-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多