【问题标题】:How to Write to a Specific Address in a File in C如何在 C 中写入文件中的特定地址
【发布时间】:2016-09-28 06:32:49
【问题描述】:

我要做的就是将一个 long int 写入偏移 0x18 和另一个单独的 long int 偏移 0x1C 到我打开的文件中。这些偏移量始终包含我正在处理的文件格式的相关数据,因此无需担心——我需要做的就是使这些地址处的值等于某个指定的数字。我打开文件没有问题,但我不确定如何完成,因为我对 C 不是很有经验。

现在我用 fopen() 以写入模式打开文件,用 fseek 寻找 0x18,用 fputs 写入“XXXXX”(XXXXX 只是一些数字),再次寻找 0x1C,再次做同样的事情,并关闭文件。我不仅觉得这种方法是错误的,而且它什么也没做,我也不知道为什么。我是对的,我应该以其他方式解决这个问题,还是我只是错过了什么?

编辑:代码:

void modify_data(unsigned long int samp1, unsigned long int samp2, char fname[]) {
FILE * newfile;
newfile = fopen(fname, "w");
fseek(newfile, 0x18, SEEK_SET);
fputs("180000", newfile); // 180000 is a placeholder while I test
fseek(newfile, 0x1C, SEEK_SET);
fputs("600000", newfile); // 600000 is a placeholder while I test
fclose(newfile);
}

int main(int argc, char * argv[]) {
char fname[sizeof(argv[1])];
strcpy(fname, argv[1]);
modify_data(0, 0, fname); // the first two arguments are placeholders while I test
return 0;
}

【问题讨论】:

  • 缺少any 代码来显示您真正 在做什么对您的问题没有任何帮助。提供minimal, complete, and verifiable example 说明您所拥有的,以及到目前为止您为缩小问题范围所做的工作。
  • 是什么让你认为这种做法是错误的?
  • 顺便说一句:fputs 不是您需要的功能。您必须使用fwrite 函数。
  • 在我的机器上,对于机器类型long,0x18 处的数据将与 0x1C 处的数据重叠。您必须使用 32 位系统。但是,fseek()fwrite() 是您需要的功能。
  • 不,我使用的是 64 位系统。我可能弄错了,但我认为长整数是 32 位,长整数是 64;不过,我很可能弄错了。

标签: c io


【解决方案1】:

非错误检查非测试代码片段:

long value1 = 18000;
long value2 = 60000;

FILE *fp = fopen("thefile", "r+");  // or "r+b" on Windows
fseek(fp, 0x18, SEEK_SET);
fwrite(&value1, sizeof long, 1, fp);
fseek(fp, 0x1c SEEK_SET);
fwrite(&value2, sizeof long, 1, fp);

如果long 的大小在您的平台上不是 32 位,您需要将 long 替换为适当的 32 位类型,很可能是 int

fputs 的解决方案不起作用。

fputs("180000", newfile);

将字符串“180000”写入文件,而不是 32 位值 18000。

【讨论】:

  • 是的,我就是这么想的,但是 fwrite 的文档说它们是用于二进制文件的,我可能误解了。我会试一试。你能解释一下为什么我必须使用 & 运算符吗?只会说 value1 不会写 value1 吗?
  • 所以你的文件是不是二进制文件,也许你应该显示那个文件,或者至少是那个文件的开头。 fwrite 想要一个内存地址,因此您需要 & 运算符,阅读 fwrite 手册页。字符串“18000”和数字 18000 是两个截然不同的东西。
  • 绝对不是纯文本,如果这就是你的意思。在这里复制和粘贴十六进制看起来很丑陋。这是一个音频文件。
  • 那你当然需要fwrite。顺便说一句,在程序的最终版本中,您需要添加错误检查,尤其是测试fopen是否返回NULL,这意味着由于某种原因无法打开文件(主要是因为它不存在)。跨度>
  • 我对我的代码进行了编辑,它现在正确地编辑了地址,但它也使所有其他值都为 0,并在编辑 0x1C 后立即崩溃,让我认为它正在创建一个新文件。我需要 w+ 来覆盖吗?
【解决方案2】:

你可能想要这个:

#include <stdio.h>

void modify_data(unsigned int samp1, unsigned int samp2, char fname[])
{
  FILE * newfile;
  newfile = fopen(fname, "r+");  // or "r+b" on Windows
  if (newfile != NULL)
  {
    printf("Could not open file");
    return;
  }

  fseek(newfile, 0x18, SEEK_SET);
  fwrite(&samp1, sizeof (unsigned int), 1, newfile);
  fseek(newfile, 0x1c, SEEK_SET);
  fwrite(&samp2, sizeof (unsigned int), 1, newfile);
}

int main(int argc, char * argv[])
{
  modify_data(0, 0, argv[1]); // the first two arguments are placeholders while I test
  return 0;
}

【讨论】:

  • 我刚刚意识到这个问题:它写得很好,但它是用小端写的;我需要它是大端的。我不认为有什么好方法可以做到这一点?
  • 简单,您只需在将其写入文件之前convert your value to big endian
  • 嗯,是的,但问题是我如何做到这一点。我以前从未使用过位移运算符,我觉得我需要用它来做这件事。除非某个库中有内置函数(可能没有)。
  • 点击我评论中的链接。
  • 在追踪图书馆后终于让它工作了。非常感谢您容忍我。
猜你喜欢
  • 1970-01-01
  • 2014-05-18
  • 1970-01-01
  • 1970-01-01
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-13
相关资源
最近更新 更多