1

テキスト ドキュメントを読み書きし、それに対して操作を実行しようとしています。

#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 がスローされます。私は...ここで何が起こっているのか本当に理解できません。私がいるレベルで。

#

回答後の編集: 固定コードの動作

#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;
}
4

2 に答える 2

6

READ(恐ろしい命名規則BTW)を返すと主張してcharいますが、コードはそのように動作していますchar*

strcat("%s", ret)宛先 ("%s") に "ret" を追加するスペースがないため、これは不適切です)

于 2013-07-02T05:40:05.257 に答える
2

これは私が見る大きな問題です。

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

1つはstrcat、フォーマット仕様を取りません(おそらくあなたは考えているでしょうsprintf)。

"%s"2 つ目は、文字列リテラル (や など)の内容を変更することはできません""。で行ったように、スペースを割り当てるか、文字配列を使用する必要があり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";

一方のパスはこの文字列リテラルを返し、もう一方のパスはmalloced データを返すため、呼び出し元の関数は呼び出すかどうかを知りfreeません。mallocこれは、常にed メモリを返すことで修正できます。

if (!ptr_file) {
    ret = realloc(ret, strlen("FAIL\n") + 1);
    strcpy(ret, "FAIL\n");
    return ret;
}
于 2013-07-02T05:41:43.603 に答える