使用字符串缓冲区读取和写入文件

时间:2013-07-02 05:37:15

标签: c segmentation-fault

我正在尝试读取和编写文本文档,然后对其执行操作。

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

int WRITE(char *FILENAME, char *DATA)
{
    FILE *ptr_file;
    ptr_file =fopen(FILENAME, "w");
    if (!ptr_file)
        return 1;
    fprintf(ptr_file,"%s", DATA);
    fclose(ptr_file);
    return  0;
}

char READ(char *FILENAME)
{
    FILE *ptr_file;
    char buf[1000];
    char* ret="";
    ptr_file =fopen(FILENAME,"r");
    if (!ptr_file)
        return "FAIL\n";
    while (fgets(buf,1000, ptr_file)!=NULL)
        ret=strcat("%s",ret);
    fclose(ptr_file);
    return ret;
}

int main()
{   
    char* DAT = "lol";
    char* FILENAME = "output.txt";
    char* NEWDAT;
    int count=0;
    int max=10;

    while (count<max) {
        NEWDAT=READ(FILENAME);
        WRITE(FILENAME,strcat(DAT,NEWDAT));
        count++;
    }
    READ(FILENAME);
    return 0;
}

这就是编译器所说的

gcc -Wall -o "filewrite" "filewrite.c" (in directory: /home/x/Documents/programming/C code)
filewrite.c: In function ‘READ’:
filewrite.c:22:3: warning: return makes integer from pointer without a cast [enabled by default]
filewrite.c:26:2: warning: return makes integer from pointer without a cast [enabled by default]
filewrite.c: In function ‘main’:
filewrite.c:38:9: warning: assignment makes pointer from integer without a cast [enabled by default]
Compilation finished successfully.

然后它抛出了Code 139 / Segmentation Fault。我......真的不能开始明白这里发生了什么;在我所处的水平。

POST-ANSWERS编辑: 固定代码工作

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

int WRITE(char *FILENAME, char *DATA)
{
    FILE *ptr_file;
    ptr_file =fopen(FILENAME, "w");
    if (!ptr_file)
        return 1;
    fprintf(ptr_file,"%s", DATA);
    fclose(ptr_file);
    return  0;
}

char* READ(char *FILENAME)
{
    FILE *ptr_file;
    char buf[1000];     
    char *ret = malloc(1); 
    int retsize = 1; 
    ret[0]='\0';
    buf[0]='\0';

    ptr_file = fopen(FILENAME,"r");
    if (!ptr_file) {
        ret = realloc(ret, strlen("FAIL\n") + 1);
        strcpy(ret, "FAIL\n");
        return ret;
    }
    while (fgets(buf,1000, ptr_file)!=NULL)
    {
        retsize += strlen(buf)+1;  // new size is old size + length of string in buf
        ret = realloc(ret, retsize);  // increase the size of the allocation
        strcat(ret, buf);          // append the new data
    }
    fclose(ptr_file);
    return ret;
}

int main()
{   
    char* DAT = malloc(1);
    int datsize = 1;
    char* FILENAME = "output.txt";
    char* NEWDAT; 
    strcpy(DAT, "LOL");
    int count=0;
    int max=5;

    while (count<max) {
        NEWDAT=READ(FILENAME);
        datsize += strlen(NEWDAT) + strlen(DAT);
        DAT = realloc(DAT, datsize);
        strcat(DAT,NEWDAT);
        WRITE(FILENAME,DAT);

        printf("%i\n",count);
        printf("%s\n",DAT); 
        count++;
    }
    READ(FILENAME);
    return 0;
}

2 个答案:

答案 0 :(得分:6)

READ(可怕的命名惯例BTW)声称返回char,但您的代码表现得像char*

strcat("%s", ret)是错误的,因为目的地(“%s”)没有任何空间可以附加“ret”)

答案 1 :(得分:2)

这是我看到的问题。

char* ret="";
...
    ret=strcat("%s",ret);

首先,strcat没有采用格式规范(也许您正在考虑sprintf)。

对于两个,您无法修改字符串文字的内容(如"%s""")。您必须像使用buf一样分配空间或使用字符数组。

如果您想要返回buf的累计内容,请尝试

char *ret = malloc(1);
int retsize = 1;
ret[0] = '\0'; // this line could also be written: `strcpy(ret,"");` or `*ret = 0;`
...
while (fgets(buf,1000, ptr_file)!=NULL)
{
    retsize += strlen(buf)+1;  // new size is old size + length of string in buf
    ret = realloc(ret, retsize);  // increase the size of the allocation
    strcat(ret, buf);          // append the new data
}

要删除编译器警告,请添加

#include <stdlib.h>  // malloc

并且正如其他人所说的那样。函数的返回类型应为char *,以匹配其值返回的变量。


寻址已编辑的代码。

NEWDAT正在接收READ读取的数据。所以它的DAT需要调整大小。

    ...
    char* DAT = malloc(1);
    int datsize = 1;
    char* FILENAME = "output.txt";
    char* NEWDAT; 
    DAT[0]='\0';
    int count=0;
    int max=5;

    while (count<max) {
        NEWDAT=READ(FILENAME);
        datsize += strlen(NEWDAT) + 1;
        DAT = realloc(DAT, datsize);
        strcat(DAT,NEWDAT);
        WRITE(FILENAME,NEWDAT);
        ...

正如BrainSteel指出的那样,READ函数还有另一个问题,尽管这个程序运行并不重要。

if (!ptr_file)
    return "FAIL\n";

由于一个路径返回此字符串文字,而另一个路径返回malloc ed数据,因此调用函数将不知道是否调用free。我们可以通过始终返回malloc内存来解决此问题。

if (!ptr_file) {
    ret = realloc(ret, strlen("FAIL\n") + 1);
    strcpy(ret, "FAIL\n");
    return ret;
}