C语言 文件方面 段错误 核心已转储 以及字符串查找删除的问题

2025-02-25 05:44:41
推荐回答(4个)
回答1:

有几个问题:

  1. 文件在读取了你的字符串后,文件指针位置已经到了该字符串后面,如果puts则会在字符串后面输出,比如:文件内容是aaaa\nbbbb\ncccc\n,你读到bbbb行后,文件指针指向cccc\n的首字符,如果puts的话会覆盖cccc\n。按照设计目的,你应当让文件指针返回字符串bbbb\n的首字符再输出。

  2. 在输出了覆盖字符串后,还应当将文件后面所有行重新写一遍才行。

    比如文件内容是aaaa\nbb1bb\ncccc\n,如果只删除b1则变成aaaa\nbbb\nb\ncccc\n,而实际上应当改成aaaa\nbbb\nccc\n。

  3. 用同一个文件实现这个功能时,文件的结束很难截断。

建议如下修改:

    FILE *fp,*tp;
    int l;
    char *p;
    char filename[80] = { "a.txt" };
    char filename1[80] = { "b.txt" };
    char r[] = { "abc123" };
    char buff[256];
    int success = 0;
    if (fp = fopen(filename, "r"))
    {
        if (tp = fopen(filename1, "w+"))
        {
            l = strlen(r);
            while ( !feof(fp) )
            {
                fgets(buff, 200, fp);
                if (p = strstr(buff, r))    strcpy(p, p + l);
                fputs(buff, tp);
            }
            fclose(tp);
            success = 1;
        }
        else printf("cann't open target file!\n");
        fclose(fp);
    } else printf("can't open file!\n");
    if (success) { remove(filename); rename(filename1, filename); }
【测试】

原a.txt内容为:

abcdefghijklmn
1234567890
a1a2abc123a4a5a6
b1b2b3b4b
ccccc
运行程序后为:

abcdefghijklmn
1234567890
a1a2a4a5a6
b1b2b3b4b
ccccc

注意:原a.txt文件中最后一行后面不换行结束。

回答2:

p=strstr(buff,r); //char *p ,这里是不是表示找到了缓冲区里 要删的字符串了,并指向那个字符串首地址?

你的理解没错,不过有个前提:确实能找到。如果找不到就会返回0x0,你后面strcpy就会出错。

另外,这句话之后p指向buff中r首次出现的地方,换言之p在buff中间某个位置。
如果p在buff靠后的位置上,然后s又比较长,strcpy(p, s);(这里实际上是将s拷贝到buff中某个位置)就会导致buff最后一个字节后面的内存被意外修改。
既然是linux下,建议使用strncpy;还有strstr返回值要判断一下是不是0x0再使用。

上述均为猜测,具体定位需要知道p=strstr(buff,r);后p的输出,buff的大小,还有s的值。如果还有问题请追问。

PS:直接从一个已有文件中删除某几个字节是不可能的。因为文件在硬盘上是连续存储的,不可能删掉一个字节然后后面的内容自动前移。要实现这个功能只有使用临时文件:将新的整个文件输出到临时文件中,最后删除源文件,将临时文件重命名为源文件的名字。

回答3:

如果p在buff靠后的位置上,然后s又比较长,strcpy(p, s);(这里实际上是将s拷贝到buff中某个位置)就会导致buff最后一个字节后面的内存被意外修改。
既然是linux下,建议使用strncpy;还有strstr返回值要判断一下是不是0x0再使用。

上述均为猜测,具体定位需要知道p=strstr(buff,r);后p的输出,buff的大小,还有s的值。如果还有问题请追问。

回答4:

在linux下有个方法可以快速定位是哪里出错.
[利用core dump文件]
1.设置生成的core文件大小
$ulimit unlimited #设置文件大小为无限
2.
# echo “/log/History/core.%e.%p” >/proc/sys/kernel/core_pattern #这里是用root权限才能修改! core文件放在/log/History/下

3.调试生成出来的core文件
$ gdb ./coreDump core.11531

可以看到如下信息:
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004004c2 in main () at coreDump.c:6
6 *null_ptr = 10; //对空指针指向的内存区域写,会发生段错误
(gdb)

希望对你有帮助,如果你是Linux平台的话