【问题标题】:Write a program which reverses the order of the bytes in a binary file with a limited number of file positioning steps编写一个程序,以有限数量的文件定位步骤反转二进制文件中的字节顺序
【发布时间】:2012-07-17 15:48:47
【问题描述】:

我需要编写一个程序来反转给定二进制文件中字节的顺序。它接受命令行中的文件名。此外,它可以使用文件定位功能,如 fseek 不超过固定次数。

这是我写的一段代码,它没有使用固定次数:

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

int main(int argc, char** argv) {

    if (argc>2) {
        printf("Please enter a valid file name");
        return 1;
    } else {
        FILE* file;
        file=fopen(argv[1], "r");
        if (file==NULL) {
            printf("Please enter a valid file name");
            return 1;
        } else {
            FILE* fileBackUp;
            fileBackUp=fopen("c:\backupFile.txt", "w+");
            fseek(file, 0, SEEK_END);
            fseek(file, -1, SEEK_CUR);
            while (ftell(file)>=0) {
                int c= fgetc(file);
                fputc(c, fileBackUp);
                fseek(file, -2, SEEK_CUR);
            }

            fseek(fileBackUp, 0, SEEK_SET);

            int c;
            while (!feof(fileBackUp)) {
                c=fgetc(fileBackUp)
                fputc(c,file);
            }

            fclose(fileBackUp);
            fclose(file);
        }
    }
    return 1;
}

它为此使用了一个额外的文件。我当然相信有一种更短的优雅方法可以按照要求减少步骤。有什么建议吗?

还有一件事:好像第一个条件总是被满足,怎么回事?

【问题讨论】:

  • 应该将其标记为“作业”吗?如果没有,为什么限制你可以调用多少个 fseek?
  • 你想反转bits还是反转bytes
  • @mfrankli:7 月份的作业? :) 不,这是我试图回答的过去测试中的一个问题。
  • 不——你仍然只是颠倒字节的顺序——如果你想颠倒所有的位,那么你也需要对每个字节做一点颠倒。
  • 否 - 文件 I/O 在字节级别工作。

标签: c file binary


【解决方案1】:
#include <stdio.h>

long max(long v1, long v2) { return v1 >= v2 ? v1 : v2; }
long min(long v1, long v2) { return v1 >= v2 ? v2 : v1; }
void invert_bits(char *arr, size_t size);

int main(int argc, char *argv[]) {
  size_t  read_sz;
  FILE * infile = fopen(argv[1], "r");
  fseek(infile, 0, SEEK_END);
  long file_sz = ftell(infile);
  long offset  = file_sz;
  long total_read = 0;
  long num_seeks  = 10;
  size_t  buffer_sz = (file_sz + num_seeks - 1) / num_seeks;
  char    buffer[buffer_sz];
  while (file_sz > total_read) {
    if ((offset + num_seeks - 1) / num_seeks < buffer_sz) {
      buffer_sz = offset / num_seeks;
    }
    offset = max(0, offset - buffer_sz);
    fseek(infile, offset, SEEK_SET);
    read_sz = fread(buffer, 1,
        min(buffer_sz, file_sz - total_read), infile);
    total_read += read_sz;
    invert_bits(buffer, read_sz); 
    num_seeks--;
  }
  fclose(infile);
}

void invert_bits(char *arr, size_t size) {
  size_t i;
  int j;
  for (i = size; i > 0; i--) {
    char v = arr[i - 1];
    char o = 0;
    for (j = 0; j < 8; j++) {
      o |= v & 1;
      v >>= 1;
      o <<= 1;
    }
    printf("%c", o);
  }
}

【讨论】:

  • 感谢您的回答。 file_sz 是文件开头的字节数,对吗?为什么每次都减去缓冲值?
  • 你确定“file_sz -= buffer_sz;”在while循环结束时是否正确?它对我不起作用。
  • 即使没有它,也不正确。有一个问题。我们再次读取相同的字节。试试 file-size=10, buffer-size=4.
  • 这仍然根据文件大小在 while() 循环中调用 fseekfread 可变次数。不要使用 1024 的恒定缓冲区大小,而是使用文件大小的恒定分数。我不确定您为什么要这样做,但这是问题的限制(可能是为了测试学生对动态内存分配和文件 IO 的了解?)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-19
  • 2013-05-13
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
  • 2018-12-11
相关资源
最近更新 更多