免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 4107 | 回复: 13
打印 上一主题 下一主题

大侠:c语言修改文件出错,求解! [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-01-10 22:02 |只看该作者 |倒序浏览
20可用积分
求大侠告诉我该怎么改!!!

1.程序思路:
    先从文本文件test中读出内容,放到char tmp[200]中;
    读的过程,遇到“name=apple”时,不将它放入tmp[200]中,而是换成“name=banana”;
    最后再将tmp[200]的内容写入文本文件test.


2.文本文件test中的内容:
sort=fruits;
name=apple
price=4


3.程序:(程序代码见下,运行在linux下)
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define txtfile "test"
int main()
{
        FILE *fp, *fp2; char tmp[200];char *line; size_t len; int ret;

        //read content form txtfile;
        fp=fopen(txtfile,"r");
        if(fp == NULL){perror(txtfile);exit(EXIT_FAILURE);}
        while ((read = getline(&line, &len, fp)) != -1) {
                if(line=="\n")continue;
                if(strstr(line,"name=apple"))
                        strcat(tmp,"name=banana");
                else
                        strcat(tmp,line);
                strcat(tmp,"\n");
        }
        fclose(fp);

        //write content from tmp back to txtfile;
        fp2 = fopen(txtfile, "w");
        if(fp == NULL){perror(txtfile);exit(EXIT_FAILURE);}
        ret=fputs(tmp,fp);
        if(ret <0||ret==EOF)
                printf("Write error!\n");
        fclose(fp2);

        return 0;
}


4.执行时出现错误:
[apples@dnisw3 test]$ ./a.out
*** glibc detected *** ./a.out: realloc(): invalid pointer: 0x008acfc0 ***
======= Backtrace: =========
/lib/i686/nosegneg/libc.so.6(realloc+0x3ab)[0x91e84b]
/lib/i686/nosegneg/libc.so.6[0x91e991]
/lib/i686/nosegneg/libc.so.6(realloc+0x3c)[0x91e4dc]
/lib/i686/nosegneg/libc.so.6(getdelim+0x16a)[0x90b4ca]
/lib/i686/nosegneg/libc.so.6(getline+0x33)[0x9088c3]
./a.out[0x80485ef]
/lib/i686/nosegneg/libc.so.6(__libc_start_main+0xdc)[0x8c9f2c]
./a.out[0x8048461]
======= Memory map: ========
00893000-008ac000 r-xp 00000000 08:01 7997060    /lib/ld-2.5.so
008ac000-008ad000 r--p 00018000 08:01 7997060    /lib/ld-2.5.so
008ad000-008ae000 rw-p 00019000 08:01 7997060    /lib/ld-2.5.so
008b4000-009ef000 r-xp 00000000 08:01 7997061    /lib/i686/nosegneg/libc-2.5.so
009ef000-009f1000 r--p 0013a000 08:01 7997061    /lib/i686/nosegneg/libc-2.5.so
009f1000-009f2000 rw-p 0013c000 08:01 7997061    /lib/i686/nosegneg/libc-2.5.so
009f2000-009f5000 rw-p 009f2000 00:00 0
00a98000-00a99000 r-xp 00a98000 00:00 0          [vdso]
00c9e000-00ca9000 r-xp 00000000 08:01 7997070    /lib/libgcc_s-4.1.1-20061011.so.1
00ca9000-00caa000 rw-p 0000a000 08:01 7997070    /lib/libgcc_s-4.1.1-20061011.so.1
08048000-08049000 r-xp 00000000 08:03 24414215  /home/apples/test/a.out
08049000-0804a000 rw-p 00000000 08:03 24414215  /home/apples/test/a.out
0903c000-0905d000 rw-p 0903c000 00:00 0
b7ef1000-b7ef2000 rw-p b7ef1000 00:00 0
b7f0d000-b7f0f000 rw-p b7f0d000 00:00 0
bfd49000-bfd5f000 rw-p bfd49000 00:00 0          [stack]
Aborted

最佳答案

查看完整内容

getline函数用的有问题。要么char *line=NULL;要么line指向malloc的内存tmp要先初始化strcat(tmp,"\n"); 这句也有点问题,结果会多出空行

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
2 [报告]
发表于 2009-01-10 22:02 |只看该作者

回复 #1 apple_7095 的帖子

getline函数用的有问题。要么
char *line=NULL;
要么line指向malloc的内存
       getline()  reads  an entire line from stream, storing the address of the buffer containing the text into *lineptr. The buffer is null-terminated and includes the newline character, if one was found.
       If *lineptr is NULL, then getline() will allocate a buffer for storing the line, which should be freed by the user program.   Alternatively,  before calling getline(), *lineptr can contain a pointer to a malloc()-allocated buffer *n bytes in size. If the buffer is not large enough to hold the line, getline() resizes it with realloc(),  updating *lineptr and *n as necessary. In either case, on a successful call, *lineptr and *n will be updated to reflect the buffer address and allocated size respectively.


tmp要先初始化
strcat(tmp,"\n"); 这句也有点问题,结果会多出空行

论坛徽章:
3
天蝎座
日期:2014-10-25 13:44:312015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:48:31
3 [报告]
发表于 2009-01-10 22:23 |只看该作者
无聊,把代码格式化了一下,一下子就看到一个BUG了




#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define txtfile "test"
int main()
{
        FILE *fp, *fp2; char tmp[200];char *line; size_t len; int ret;

        //read content form txtfile;
        fp=fopen(txtfile,"r");
        if(fp == NULL)
       {
              perror(txtfile);
              exit(EXIT_FAILURE);
       }


        while ((read = getline(&line, &len, fp)) != -1)
        {
                if(line=="\n")
                {
                       continue;
                }

                if(strstr(line,"name=apple"))
                {
                        strcat(tmp,"name=banana");
                }
                else
                {
                        strcat(tmp,line);
                }

                strcat(tmp,"\n");
        }
        fclose(fp);

        //write content from tmp back to txtfile;
        fp2 = fopen(txtfile, "w");
        if(fp == NULL)——fp2???
        {
               perror(txtfile);
               exit(EXIT_FAILURE);
        }

        ret=fputs(tmp,fp);
        if(ret <0||ret==EOF)
        {
                printf("Write error!\n");
        }

        fclose(fp2);

        return 0;
}

论坛徽章:
3
天蝎座
日期:2014-10-25 13:44:312015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:48:31
4 [报告]
发表于 2009-01-10 22:24 |只看该作者
另外
局部变量未初始化,比如tmp[200]。


看程序的要求,以及代码的风格,估计楼主还是学生吧;

嗯,一点小建议,代码写完了,不用立即就编译,立即就运行,先看看代码是不是有明显的BUG;

[ 本帖最后由 ilex 于 2009-1-10 22:25 编辑 ]

论坛徽章:
3
戌狗
日期:2014-09-10 17:07:162015年辞旧岁徽章
日期:2015-03-03 16:54:15wusuopu
日期:2016-06-17 17:43:45
5 [报告]
发表于 2009-01-10 23:49 |只看该作者
简单修改
  1. #define _GNU_SOURCE
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>

  5. #define txtfile "test"

  6. int main()
  7. {
  8.     FILE *fp, *fp2;
  9.     char tmp[200];
  10.     char *line=NULL;
  11.     size_t len; int ret;

  12.     memset(tmp, 0x00, sizeof(tmp));

  13.     //read content form txtfile;
  14.     fp=fopen(txtfile,"r");
  15.     if(fp == NULL) {
  16.         perror(txtfile);
  17.         exit(EXIT_FAILURE);
  18.     }

  19.     while ((ret= getline((char **)&line, &len, fp)) != -1) {
  20.         //if(line=="\n")continue;
  21.         if (line[0] == '\n') continue;
  22.         if(strstr(line,"name=apple"))
  23.             strcat(tmp,"name=banana\n");
  24.         else
  25.             strcat(tmp,line);
  26.         //strcat(tmp,"\n");
  27.     }
  28.     if (line != NULL) {
  29.         free(line);
  30.     }
  31.     fclose(fp);

  32.     //write content from tmp back to txtfile;
  33.     fp2 = fopen(txtfile, "w");
  34.     if(fp2 == NULL) {
  35.         perror(txtfile);
  36.         exit(EXIT_FAILURE);
  37.     }
  38.     ret=fputs(tmp,fp);
  39.     if(ret <0||ret==EOF)
  40.         printf("Write error!\n");
  41.     fclose(fp2);

  42.     return 0;
  43. }
复制代码

论坛徽章:
0
6 [报告]
发表于 2009-01-11 00:50 |只看该作者
怎么看这段代码内容跟man手册 man getline中的例子越一样

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
7 [报告]
发表于 2009-01-11 08:53 |只看该作者

论坛徽章:
0
8 [报告]
发表于 2009-01-11 11:29 |只看该作者
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define txtfile "test"
int main()
{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FILE *fp, *fp2; char tmp[200];char *line; size_t len; int ret;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//read content form txtfile;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fp=fopen(txtfile,"r");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(fp == NULL)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(txtfile);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}


&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while ((read = getline(&line, &len, fp)) != -1)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(line=="\n")
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;continue;
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(strstr(line,"name=apple"))
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(tmp,"name=banana");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(tmp,line);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strcat(tmp,"\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//write content from tmp back to txtfile;

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fp2 = fopen(txtfile, "w");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(fp == NULL)——fp2???
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;perror(txtfile);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;exit(EXIT_FAILURE);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ret=fputs(tmp,fp);
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ret <0||ret==EOF)
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("Write error!\n");
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;fclose(fp2);

&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return 0;
}


单凭LZ现在给出的代码应该通不过compile的,getline是string类里的成员函数,怎么可以这样用的呢?????

论坛徽章:
0
9 [报告]
发表于 2009-01-11 13:15 |只看该作者
原帖由 ilex 于 2009-1-10 22:24 发表
另外
局部变量未初始化,比如tmp[200]。


看程序的要求,以及代码的风格,估计楼主还是学生吧;

嗯,一点小建议,代码写完了,不用立即就编译,立即就运行,先看看代码是不是有明显的BUG;


谢谢你啊。。是小弟传帖子时为了简单就直接把靠前的代码copy了过来。。。。
让大侠失望了,小弟刚毕业半年,c确实学的不好,正在狂补。。。
最后,再次真诚的感谢,还望仁兄们多多指教啊。。。有什么问题麻烦赶紧告给我指明。。。

论坛徽章:
0
10 [报告]
发表于 2009-01-11 13:18 |只看该作者

问题解决了,多谢各位。

各位说的很正确,再次感谢啊!!!

现将运行正确的代码贴出来:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define txtfile "test"
#define buff_len 200
#define line_len 64

int main()
{
        FILE *fp, *fp2;
        char tmp[buff_len]={0};
        char *line=(char *)malloc(line_len);
        size_t len;
        ssize_t read;
        int ret;
        //read content form txtfile;
        fp=fopen(txtfile,"r");
        if (fp == NULL){
                perror(txtfile);
                exit(EXIT_FAILURE);
        }
        while ((read = getline(&line, &len, fp)) != -1) {
                if(strstr(line,"apple")){
                        strcat(tmp,"name=banana");
                        strcat(tmp,"\n");
                }
                else
                        strcat(tmp,line);
        }
        fclose(fp);
        //write content from tmp back to txtfile;
        fp2 = fopen(txtfile, "w");
        if (fp2 == NULL){
                perror(txtfile);
                exit(EXIT_FAILURE);
        }
        ret=fputs(tmp,fp2);
        if(ret<0||ret==EOF)
                printf("Write error!\n");
        fclose(fp2);

        return 0;
}

怎么改进???

各位:
       这个程序里有几个问题,第一,程序中两次打开同一文件,能否只打开一次,该怎么写?
第二,getline函数是<string.h>里的,纯c里面是不是没这个函数啊,怎么替换掉它呢?
第三,程序写的很笨,有高手能写得更简洁高效么?
当然,可能还有其他小弟没发现的问题,请各位指出来!!!

最后,重申本程序的目的:c语言修改一个文本文件中的一段字符串。期待!!!

[ 本帖最后由 apple_7095 于 2009-1-11 13:27 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP