【问题标题】:Overwriting an ID3v2 tag in C using fwrite()使用 fwrite() 覆盖 C 中的 ID3v2 标签
【发布时间】:2013-10-10 17:27:30
【问题描述】:

由于某种原因,当我调用 fwrite() 时,它不会覆盖指针指向的文件。当我运行程序时,它显示文件的标签被用户指定的输入标签替换。在我使用单独的代码检查文件以查看当前标签后,标签根本没有被替换。我相信我使用 fwrite 的方式有问题,并认为它真的会覆盖文件。在这种情况下,标签是标题。代码如下:

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

char title[30];
char title1[30];

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

FILE *fPtrs;

    // print the current tag
fPtrs = fopen(argv[1],"r+b");
fseek(fPtrs,-125,SEEK_END);
fread(title1,1,30,fPtrs);
strncpy(title,title1,30);
printf("%s\n",title);
fclose(fPtrs);

    // call to overwrite the current tag
fPtrs = fopen(argv[1],"w+b");
title_tag(fPtrs,argv[2]);   
fclose(fPtrs);

    // print the tag of the should be overwritten file
fPtrs = fopen(argv[1],"r+b");
fseek(fPtrs,-125,SEEK_END);
fread(title1,1,30,fPtrs);
strncpy(title,title1,30);
printf("%s\n",title);
fclose(fPtrs);

return 0;
}

#include<stdio.h>
void title_tag(FILE* fName, char title_s[]){

fseek(fName,-125,SEEK_END);
fwrite(title_s,1,30,fName);

}

这是我在大学里从事的一个项目,我们被告知不允许使用 id3lib -.-

【问题讨论】:

  • fseekfreadfwrite 都返回错误。检查这些可能有助于指出问题所在。

标签: c file-io tags overwrite id3v2


【解决方案1】:
  1. 您没有进行任何输入验证。您的程序依赖于两个命令行参数,但您没有测试 argc == 3 或类似的东西。

  2. 没有错误检查。在盲目假设第一个命令行参数是正确指定的文件名之后,您没有检查 fopen() 调用的返回值来验证调用是否成功。你也没有做任何检查来验证你打开的文件是否有一个 ID3v1 标签,你只是假设它存在。

  3. 当您调用fread() 时,您并不能确定您读取的是一个有效的字符串,但您会继续将其视为一个字符串。 (您正在读取一个 30 字节的字段,但在我看来,它不需要是一个 null-terminated 30 字节的字段。如果曲目标题是 30 字节会发生什么长吗?

  4. 为什么要将标题从title 复制到title1?完全撇开你没有确保它是空终止的,因此应该是空终止它或使用memcpy(),你对副本做的唯一事情就是将它传递给printf()。复制它对你有什么好处?

  5. 您不应该关闭/重新打开/关闭/重新打开文件。第一次打开它时,您使用的是模式"r+b",它会打开文件以进行读取和写入,因此您需要做的就是fseek()。 (当然,还有完整性检查,看看您是否可以更新现有的 ID3v1 标记,或者是否需要附加一个。)

  6. 真的不应该关闭/重新打开/关闭/重新打开文件。打开模式"w+b",当您不必要地关闭/重新打开文件以更新它时,如果文件已经存在,则记录为将文件截断为零长度,或者创建一个新的否则归档。

  7. 您传递给 title_tag() 函数的内容。

    • 由于您正在使用它,title_tag() 的第二个参数需要是至少 30 字节的存储块。你正在传递它argv[2],但不能保证是这样。您需要将 argv[2] 复制到您自己的存储中,然后将其传递。

    • 您已经编写了title_tag() 函数,因此有人可能会错误地认为函数中的第二个参数是一个数组。然而,由于 C 语言的机制,在函数的上下文中,参数只是一个指向字符的指针。 (您可以将其写为char title_s[],但在 C 中,如果您将数组作为参数传递给函数,则函数实际获得的是指向数组第一个元素的指针。对于大多数目的,这功能上没有区别。)

那里。希望对您有所帮助。

【讨论】:

    【解决方案2】:

    强烈推荐使用 id3lib。将允许您更好地控制 id3 标记的操作,而不仅仅是尝试写入原始文件

    http://id3lib.sourceforge.net/

    【讨论】:

    • 如果你要推荐一个 (L)GPL 库,那么解释一下它所施加的限制也是值得的。 (即发布产品使用户有权获得完整的源代码或允许独立更新 id3lib 的应用程序结构)
    • 我猜,如果你这么说的话
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 1970-01-01
    • 2020-11-08
    • 2013-04-30
    • 1970-01-01
    相关资源
    最近更新 更多