You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

C语言删除文本文件指定行后残留空白问题求助

解决C语言删除文件指定行后空白残留与未知符号问题

嘿,我来帮你捋捋这个问题~你的代码里踩了几个关键小坑,导致了空白残留和未知符号的出现,咱们一步步拆解修复:

问题根源分析

  1. 空白残留的原因:你跳过目标行内容时,最后把目标行的换行符\n也写入了newstring,相当于留下了一个空行。比如原文件第2行是"abc\n",你跳过了"abc",但把最后的\n写进去了,自然就出现了空白行。
  2. 未知符号的原因:你给newstring分配了内存,但最后没有添加C字符串必须的终止符\0,这会导致后续操作(写文件、打印)访问到内存里的随机垃圾数据,也就是你看到的未知符号。
  3. 另外你的原代码还缺少写回文件的逻辑,以及一些必要的错误检查(比如文件打开失败、内存分配失败),这些都可能导致隐藏问题。

修复后的完整代码

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

void removeBook(int line){
    char *bookrecord = "records/bookrecord.csv";
    FILE *file = fopen(bookrecord,"r");
    // 检查文件是否成功打开
    if (!file) {
        perror("Failed to open file");
        return;
    }
    
    int currentline = 1;
    int count = 0, newcount = 0;
    long length; // ftell返回long类型,用long更安全
    char *string;
    char *newstring;

    // 获取文件总长度
    fseek(file, 0, SEEK_END);
    length = ftell(file);
    fseek(file, 0, SEEK_SET);
    
    // 分配内存并检查是否成功
    string = malloc(length + 1);
    if (!string) {
        perror("Failed to allocate memory for string");
        fclose(file);
        return;
    }
    
    // 读取文件内容到字符串
    fread(string, sizeof(char), length, file);
    fclose(file);
    string[length] = '\0'; // 确保字符串终止
    
    // 为新字符串分配内存
    newstring = malloc(length + 1);
    if (!newstring) {
        perror("Failed to allocate memory for newstring");
        free(string);
        return;
    }
    
    while (string[count] != '\0') {
        if (currentline == line) {
            // 跳过目标行的所有内容,包括最后的换行符
            while (string[count] != '\0' && string[count] != '\n') {
                count++;
            }
            // 如果遇到换行符,也跳过它,不写入新字符串
            if (string[count] == '\n') {
                count++;
                currentline++;
                continue; // 直接进入下一轮循环,跳过写入操作
            }
        }
        
        // 更新当前行号
        if (string[count] == '\n') {
            currentline++;
        }
        
        // 将有效字符写入新字符串
        newstring[newcount] = string[count];
        count++;
        newcount++;
    }
    newstring[newcount] = '\0'; // 关键!添加字符串终止符,避免未知符号
    
    // 将新内容写回文件
    file = fopen(bookrecord, "w");
    if (!file) {
        perror("Failed to open file for writing");
        free(string);
        free(newstring);
        return;
    }
    fputs(newstring, file);
    fclose(file);
    
    // 释放分配的内存,避免内存泄漏
    free(string);
    free(newstring);
}

int main(){ // 标准C的main函数需返回int类型
    removeBook(2);
    return 0;
}

关键修改点说明

  • 消除空白行:跳过目标行时,连最后的\n也一起跳过,并用continue跳过后续的写入逻辑,彻底移除目标行的所有痕迹。
  • 解决未知符号:在处理完所有字符后,给newstring添加终止符\0,确保它是合法的C风格字符串,避免访问垃圾内存。
  • 添加错误检查:对文件打开、内存分配等操作增加失败判断,让程序更健壮。
  • 规范代码:修正main函数的返回值类型,补充内存释放逻辑避免泄漏,完善写回文件的步骤。

如果你之后还要处理字符串中的空格,基于这个修复后的合法字符串操作,就不会再出现未知符号的问题啦~

内容的提问来源于stack exchange,提问作者Edward G

火山引擎 最新活动