2017-01-15 23 views
-2

読み込み関数を使用してファイルから読み込み、そのファイルの内容をcharの配列に格納します。問題は文字を格納していて、文字列を印刷したいということです。私の弦はどうすれば入手できますか?ファイルから読み込み、読み込み関数を使用してchar配列に格納する

#include <stdio.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
#include <stdlib.h> 
#define MAX 1024 



int main(int argc, char **argv) 
{ 
    int f1; 
    char *buf; 
    char *rez = (char*)malloc(sizeof(char)* MAX); 
    buf = (char*)malloc(sizeof(char)* MAX); 
    if((f1=open("fis4.txt", O_RDONLY)) < 0) 
    { 
     printf("Error\n"); 
     exit(1); 
    } 
    int i = 0; 
    while((read(f1, &buf,1))>0) 
    { 
     rez[i]=buf[i]; 
     i++; 
    } 

    printf("%s", rez); 

    close(f1); 

return 0; 

} 
+0

文字列は 'char'sのシーケンスです。 NUL文字 ''\ 0' 'で終了する必要があります。 NULは何を読み終えたのですか? – StoryTeller

+0

したがって、rez [i] = '\ 0'のように、whileループの外側で最後の位置に '\ 0'を追加すると動作しますか? (それでも、私は正しく理解していないと思うので) – DanielsQuestions

+0

私のコードに間違いがあります。 rez [i] = buf [0 \、1番目の位置から一度に1つの文字を読み込むので、これはすべきです。今は – DanielsQuestions

答えて

1

コードにはいくつかの問題があります。まず第一に、whileループでは、iMAXより大きいかどうかをテストする必要があります。その場合は、バッファオーバーフローを避けるためにループを終了する必要があります。今のように、ファイルが1024文字より長い場合は、配列の外側に書き込もうとしているためクラッシュします。これを回避するには、(i++後)whileループにこのコードを追加します。

if(i + 1 >= MAX){ 
    break; 
} 

break;コマンドは、whileループを終了します。

第2に、文字列はヌル文字で終わる必要があります。

rez[i] = '\0'; 
buf[i] = '\0'; 

注意をiMAXよりも大きい場合はテストするときには、私たちはヌル文字のためのスペースを残してif(i + 1 >= MAX)の代わりif(i >= MAX)をしたこと:だからあなたは、このようなwhileループの後に、各文字列にnull文字を追加する必要があります。

第3に、freeを使用しないでmallocを使用しないでください。そうしないとメモリリークが発生します。あなたはこのようなあなたのプログラムの最後にrezbufを解放する必要があります。

free(rez); 
free(buf); 

あなたのケースで動作しますが、常にmallocを使用せずにrezbufなど単純な配列を宣言するだろうではない、これに代わる:

char buf[MAX]; 
char rez[MAX]; 

MAXはマクロであり、変数ではありません。

第4に、ポインタを初期化しないでください。その代わり、NULLにそれを初期化します。

char *buf = NULL; 

しかし、あなたの場合には、直接mallocにそれを初期化する方が良いでしょう:

char *buf = (char*)malloc(sizeof(char) * MAX); 

注Cには、それが必要でも推奨されていないことmallocの結果をキャストします(ただし、C++では必須です)。したがって、次のコードはより良いでしょう:

char *buf = malloc(sizeof(char) * MAX); 

詳細については、thisを参照してください。

第5に、コメントに示唆されているように、メモリ割り当てがmallocから失敗したかどうかをチェックする必要があります。その場合は、未定義の動作を避けるためにプログラムを終了する必要があります。メモリ割り当てに失敗した場合、戻り値はmallocで、NULLになります。それはあなたがmalloc後に配置する必要があることを、このコードを与える:

if(rez == NULL || buf == NULL){ 
    printf("Memory allocation failed.\n"); 
    exit(8); 
} 

あなたがstandard return valuesをフォローしたい場合は、この場合の戻り値は8になります。もちろん、あなたが標準に従わないことを望むなら、あなたが望む価値を返すことができます。標準に準拠したい場合は、ファイルが見つからなければ戻り値も2でなければなりません(コードのように1ではありません)。マクロERROR_FILE_NOT_FOUND(2に等しい)とERROR_NOT_ENOUGH_MEMORY(8に等しい)を使用することもできます。これらのマクロはwindows.hにあります(Linuxを使用しているのでこのファイルがあるかどうかわかりませんが)。

次のようになり働くあなたのコードのバージョン:

#include <stdio.h> 
#include <stdlib.h> 
#define MAX 1024 

int main(int argc, char **argv){ 
    FILE *f1; 
    char *buf = malloc(sizeof(char) * MAX); 
    char *rez = malloc(sizeof(char) * MAX); 
    if((f1=fopen("fis4.txt", "r")) == NULL){ 
     printf("Error\n"); 
     exit(2); 
    } 
    if(rez == NULL || buf == NULL){ 
     printf("Memory allocation failed.\n"); 
     exit(8); 
    } 
    int i = 0; 
    while((buf[i] = fgetc(f1)) != EOF){ 
     rez[i] = buf[i]; 
     i++; 
     if(i + 1 >= MAX){ 
      break; 
     } 
    } 

    rez[i] = '\0'; 
    buf[i] = '\0'; 
    printf("%s", rez); 

    free(rez); 
    free(buf); 

    fclose(f1); 

    return 0; 
} 
関連する問題