我有一个二进制文件,我想在进一步处理之前从中删除前 n
个字符。我有文件指针作为输入。
我尝试使用 ftruncate
但为此我不得不创建另一个我不想要的文件指针。我尝试了以下代码,但没有帮助。
#include <stdio.h>
#include <unistd.h>
int main(void) {
FILE*f,ftemp;
f=fopen("./temp","a");
scanf("%d",&n);
fseek(f,n,SEEK_SET);
ftruncate(fileno(f),/*end of file*/ );
ftemp=f;
return 0;
}
请建议任何其他方式。
实际上前 n 个字节是二进制的,其余部分就像 asn。
谢谢
最佳答案
这是一个程序,它将删除 ./temp 的前 N 个字节,留下原始文件为 ./temp-old。 它假定文件适合内存。 您在命令行上指定 N。
/*
* THIS PROGRAM IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
* EITHER EXPRESSED OR IMPLIED.
*/
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#define ERR (-1)
int main (
int argc,
char ** argv
) {
int fdin;
int fdout;
unsigned long n;
struct stat st;
size_t sz;
ssize_t ssz;
char * data;
if (argc != 2) {
fprintf(stderr, "usage: %s nbytes\n", argv[0]);
return 1;
}
n = strtoul(argv[1], NULL, 10);
if (errno) {
fprintf(stderr, "nbytes (%s) is suspect\n", argv[1]);
return 1;
}
fdin = open("./temp", O_RDONLY, 0);
if (fdin == ERR) {
fprintf(stderr, "open input: %s\n", strerror(errno));
return 1;
}
if (fstat(fdin, &st) == ERR) {
fprintf(stderr, "stat input: %s\n", strerror(errno));
return 1;
}
sz = st.st_size;
if (sz < n) {
fprintf(stderr, "file is not that big\n");
return 1;
}
data = malloc(sz);
if (data == NULL) {
fprintf(stderr, "insufficient memory\n");
return 1;
}
ssz = read(fdin, data, sz);
if (ssz < 0) {
fprintf(stderr, "read input: %s\n", strerror(errno));
return 1;
}
if ((size_t)ssz != sz) {
fprintf(stderr, "read was short\n");
return 1;
}
(void)close(fdin);
fdout = open("./temp-new", O_CREAT|O_EXCL|O_WRONLY, st.st_mode);
if (fdout == ERR) {
fprintf(stderr, "open output: %s\n", strerror(errno));
return 1;
}
sz -= n;
ssz = write(fdout, data + n, sz);
if (ssz < 0) {
fprintf(stderr, "write output: %s\n", strerror(errno));
return 1;
}
if ((size_t)ssz != sz) {
fprintf(stderr, "write was short\n");
return 1;
}
if (close(fdout) == ERR) {
fprintf(stderr, "write close: %s\n", strerror(errno));
return 1;
}
if (link("./temp", "./temp-old") == ERR) {
fprintf(stderr, "link input: %s\n", strerror(errno));
return 1;
}
if (rename("./temp-new", "./temp") == ERR) {
fprintf(stderr, "rename output: %s\n", strerror(errno));
return 1;
}
return 0;
}
我写得很仔细,但是,当然你应该在使用前备份你的文件,以防万一......
关于c - 如何从二进制文件中删除前n个字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34657416/