如何创建删除文件某些部分的功能?例如,文件为:
-。
椅子:A23
编号:123
姓名:约书亚
-。
椅子:B12
编号:512
姓名:马库斯
-。
主席:C2
编号:1
名字:德雷克
如果输入为
B12
然后文件将变为
-。
椅子:A23
编号:123
姓名:约书亚
-。
主席:C2
编号:1
名字:德雷克
我需要此功能才能使程序正常工作,但是我不知道该怎么做。
答案 0 :(得分:2)
在与原始文件相同的目录中打开一个新文件。将要替换原始文件内容的内容写入该文件。关闭新文件。在原始文件的顶部重命名新文件。
但是也许您应该考虑使用数据库而不是文本文件。
答案 1 :(得分:1)
从面值考虑问题,请考虑使用以下组合:
您将使用步骤1的相反步骤,将文件末尾(要删除的部分之后)的资料复制到要删除的部分上,然后使用步骤2将文件大小设置为新的值。
或者,也许更简单地说,将要删除的零件之前和之后的材料复制到新文件中,然后将新文件(的内容)替换旧文件。
答案 2 :(得分:1)
您可以先将文件内容读入缓冲区。然后,您可以解析该缓冲区中的数据并将其插入到某些数据结构中,例如结构数组。一旦有了,就可以将过滤的内容重新写回到文件中。
下面是我之前写的一些示例代码(经过调整),它执行的操作与您想要的类似。它接受2个命令行争论作为输入。第一个是要读取的文件,第二个是不包括的数据(在您的情况下为chair值)。如果需要,您可以将其修改为从stdin
读取。
代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define START_SIZE 10;
#define BASE 10
typedef struct {
char *chair;
int number;
char *name;
} data_t;
typedef struct {
data_t *data;
size_t n;
} file_data_t;
char *get_file_contents(const char *);
file_data_t *insert_data(char *, const char *);
int main(int argc, char *argv[]) {
// Check arguments
if (argc != 3) {
fprintf(stderr, "Usage: ./deletefile [file] [chair]\n");
exit(EXIT_FAILURE);
}
// Get buffer
char *buffer = get_file_contents(argv[1]);
// Get structure holding data
file_data_t *file_data = insert_data(buffer, argv[2]);
// Free buffer
free(buffer);
// Open file to write to
FILE *fp = fopen(argv[1], "w");
if (fp == NULL) {
fprintf(stderr, "Count not open file\n");
exit(EXIT_FAILURE);
}
// Write to file, and free contents
for (size_t i = 0; i < file_data->n; i++) {
fprintf(fp, "-.\nChair: %s\nNumber: %d\nName: %s\n",
file_data->data[i].chair,
file_data->data[i].number,
file_data->data[i].name);
free(file_data->data[i].chair);
free(file_data->data[i].name);
}
// Free everything else
free(file_data->data);
free(file_data);
fclose(fp);
return EXIT_SUCCESS;
}
file_data_t *insert_data(char *buffer, const char *dont_keep) {
size_t buffsize = START_SIZE;
const char *delim_section = "-.", *delim_line = "\n";
const char delim_colon = ':';
char *token = NULL;
char *rest = buffer;
size_t count = 0;
// Create main structure
file_data_t *file_data = malloc(sizeof *file_data);
if (file_data == NULL) {
fprintf(stderr, "Could not allocate file data\n");
exit(EXIT_FAILURE);
}
// Allocate data elements
file_data->data = malloc(buffsize * sizeof *file_data->data);
if (file_data->data == NULL) {
fprintf(stderr, "Could not allocate %zu bytes for data\n", buffsize);
exit(EXIT_FAILURE);
}
while ((token = strtok_r(rest, delim_section, &rest)) != NULL) {
// Reallocate data if necessary
if (count == buffsize) {
buffsize *= 2;
void *ptr = realloc(file_data->data, buffsize * sizeof *file_data->data);
if (ptr == NULL) {
fprintf(stderr, "Could not reallocate %zu bytes for buffer\n", buffsize);
exit(EXIT_FAILURE);
}
file_data->data = ptr;
}
char *saveptr = NULL, *endptr = NULL;
// Parse chair
char *chair = strtok_r(token, delim_line, &saveptr);
char *chair_value = strchr(chair, delim_colon);
chair_value += 2;
// If chair value is not the same as dont_keep, proceed
if (strcmp(chair_value, dont_keep) != 0) {
// Copy chair value over
file_data->data[count].chair = strdup(chair_value);
if (file_data->data[count].chair == NULL) {
fprintf(stderr, "Could not copy chair buffer\n");
exit(EXIT_FAILURE);
}
// Parse number
char *number = strtok_r(NULL, delim_line, &saveptr);
char *number_value = strchr(number, delim_colon);
number_value += 2;
// Convert number to integer
long val = strtol(number_value, &endptr, BASE);
// Didnt find a value number
if (endptr == number_value || *endptr != '\0') {
fprintf(stderr, "Count not parse number\n");
exit(EXIT_FAILURE);
}
// Add number value
file_data->data[count].number = val;
// Parse name
char *name = strtok_r(NULL, delim_line, &saveptr);
char *name_value = strchr(name, delim_colon);
name_value += 2;
// Copy name over
file_data->data[count].name = strdup(name_value);
if (file_data->data[count].name == NULL) {
fprintf(stderr, "Coul not copy name buffer\n");
exit(EXIT_FAILURE);
}
// Increment count
count++;
}
}
file_data->n = count;
return file_data;
}
char *get_file_contents(const char *path) {
// Open file
FILE *fp = fopen(path, "r");
if (fp == NULL) {
fprintf(stderr, "Failed to open %s\n", path);
exit(EXIT_FAILURE);
}
// Go to end of file
int end = fseek(fp, 0L, SEEK_END);
if (end != 0) {
fprintf(stderr, "Could not go to end of file\n");
exit(EXIT_FAILURE);
}
// Get size of file
long buffsize = ftell(fp);
if (buffsize == -1) {
fprintf(stderr, "Count not get size of file\n");
exit(EXIT_FAILURE);
}
// Allocate buffer
char *buffer = malloc(buffsize + 1);
if (buffer == NULL) {
fprintf(stderr, "Could not allocate %ld bytes for buffer\n", buffsize);
exit(EXIT_FAILURE);
}
// Go back to start of file
int start = fseek(fp, 0L, SEEK_SET);
if (start != 0) {
fprintf(stderr, "Could not go to start of file\n");
exit(EXIT_FAILURE);
}
// Read contents of file
size_t newlen = fread(buffer, 1, buffsize, fp);
if (ferror(fp) != 0) {
fprintf(stderr, "Error reading contents of file into buffer\n");
exit(EXIT_FAILURE);
}
fclose(fp);
// Null terminate buffer
buffer[newlen++] = '\0';
return buffer;
}
输出:
$ cat file.txt
-.
Chair: A23
Number: 123
Name: Joshua
-.
Chair: B12
Number: 512
Name: Marcus
-.
Chair: C2
Number: 1
Name: Drake
$ gcc -Wall -Wextra -o deletefile deletefile.c
$ ./deletefile file.txt B12
$ cat file.txt
-.
Chair: A23
Number: 123
Name: Joshua
-.
Chair: C2
Number: 1
Name: Drake
注意:上面的代码并不是执行此任务的最佳方法,当然可以进行改进。您可以以此为基础,并加以改进。