1、使用临时文件
打开原始文件和一个临时文件,读取原始文件的每一行,然后检查是否为空行,将非空行写入临时文件,最后关闭两个文件,在删除原始文件,将临时文件重命名为原始文件名。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 256
void remove_empty_lines(const char *filename) {
FILE *src = fopen(filename, "r");
if (!src) {
perror("Failed to open source file");
return;
}
FILE *temp = fopen("temp.txt", "w");
if (!temp) {
perror("Failed to open temporary file");
fclose(src);
return;
}
char line[MAX_LINE_LENGTH];
while (fgets(line, sizeof(line), src)) {
if (strcmp(line, "\n") != 0) {
fputs(line, temp);
}
}
fclose(src);
fclose(temp);
remove(filename);
rename("temp.txt", filename);
}
int main() {
remove_empty_lines("file.txt");
return 0;
}
2、直接修改文件内容
读取文件内容到内存中,在内存中处理内容,删除空行,最后写回处理后的内容到原文件。注意修改文件的大小,不要超过内存的限制。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FILE_SIZE 1048576 // 1 MB
void remove_empty_lines(const char *filename) {
FILE *file = fopen(filename, "r+");
if (!file) {
perror("Failed to open file");
return;
}
char *buffer = malloc(MAX_FILE_SIZE);
if (!buffer) {
perror("Failed to allocate memory");
fclose(file);
return;
}
size_t len = fread(buffer, 1, MAX_FILE_SIZE - 1, file);
buffer[len] = '\0';
fseek(file, 0, SEEK_SET);
ftruncate(fileno(file), 0);
char *line = strtok(buffer, "\n");
while (line) {
if (strlen(line) > 0) {
fprintf(file, "%s\n", line);
}
line = strtok(NULL, "\n");
}
fclose(file);
free(buffer);
}
int main() {
remove_empty_lines("file.txt");
return 0;
}
3、使用文件映射(mmap)
使用 mmap
将文件映射到内存中,在内存中处理内容,删除空行,最后将修改后的内容写回文件。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
void remove_empty_lines(const char *filename) {
int fd = open(filename, O_RDWR);
if (fd == -1) {
perror("Failed to open file");
return;
}
off_t size = lseek(fd, 0, SEEK_END);
char *data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (data == MAP_FAILED) {
perror("Failed to map file");
close(fd);
return;
}
char *end = data + size;
char *p = data;
while (p < end) {
char *line_end = strchr(p, '\n');
if (!line_end) line_end = end;
if (line_end != p && (line_end == p + 1 || *(line_end - 1) != '\n')) {
memmove(data, p, line_end - p);
data += (line_end - p);
*data++ = '\n';
}
p = line_end + 1;
}
ftruncate(fd, data - data);
munmap(data, size);
close(fd);
}
int main() {
remove_empty_lines("file.txt");
return 0;
}