2016-07-21 7 views
2

私は以下の問題を説明するための小さなサンプルプログラムを持っています。fscanfが読み込み、一時変数に割り当てる3つの単語(新しい行のそれぞれ)文字列配列に転送されます。しかし、値は配列に転送されていないようです。 また、whileループの2番目のprintfから//コメントを削除すると、segフォルトが発生します。fscanf usage in c - 値が正しく保存されない

私はC言語ではかなり新しく、今ではこれらの機能の使い方を学んでいます!助けを前にありがとう!あなたのコードで

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

int main (int argc, char* argv[]) 
{ 
char* words[15]; 
char tmp[45]; 
int i = 0; 

FILE* fp = fopen("small", "r"); 

while (fscanf(fp, "%s", tmp) == 1) 
{ 
    printf("%s\n", tmp); 
    words[i] = tmp; 
    i++; 
    //printf("%s ", words[i]); 
}    
printf("\n"); 
printf("Words 0 = %s\n", words[0]); 
printf("Words 2 = %s\n", words[1]); 
printf("Words 3 = %s\n", words[2]); 

fclose(fp); 
} 

出力

pears 
apples 
zipper 

Words 0 = zipper 
Words 2 = zipper 
Words 3 = zipper 
+1

の最後にreturn 0を追加しました。 –

+0

ここに2回のダッシュがあります:http://stackoverflow.com/questions/29335910/having-trouble-with-array-being-overwritten http://stackoverflow.com/questions/16268520/c-value-being-changed-overwritten –

答えて

4

words[i] = tmp;words配列への各入力店舗への道ではありません。 tmpアレイのベースアドレスをそれぞれwords[i]以降に格納するだけで、印刷中は実際にはすべての繰り返しでtmpの最新の内容が印刷されます。

あなたは各words[i]tmp配列の内容を取得したい場合は、あなたが

  • は各words[i]にメモリを割り当て、strcpy()
  • 使用strdup()を使用してwords[i]にそれを割り当てることのいずれか。必要

どちらの場合でも、終了する前に割り当てられたメモリはfree()にする必要があります。

+0

非常に参考になりました、ありがとう! – Leon

1

私は過去に同じ問題を抱えていました。

問題は、ファイルから読み取ったときに、単語がバッファに保存され、変数tempに格納されるということです。

次の単語を読むと、バッファの内容が変わるということです。そして、これは以前の呼び出しにも影響します!

それではあなたは[1] =「りんご」あなたはリンゴと言葉を印刷し、「りんご」を読んで[0] =「梨」

あなたは、「梨」を読んで、あなたは「梨」と言葉を印刷します。しかし、words [0] = "apples"!

のように...あなたがする必要がどのような

は、すべての単語のためのmallocでメモリを割り当てるために、ファイルを読む前にある[i]と「」にそれが等しい得ます。

words[0] = ""など

ファイルの読み込みを開始するときは、tempとwords [i]にstrcpy()関数を使用する必要があります。これはあなたの問題を解決します。

私はこの問題に私が悩まされ、私をたくさん混乱させてしまったので、私はこれと簡単に答えようとしました。

0

あなたのコードの最初の重要な問題は、このラインそれはあなたに15個の文字ポインタ(char*)の配列を与える

char* words[15]; 

です。つまり、ではなく、で、15文字列の配列と同じです。文字列を格納するためのメモリがありません。

文字列を格納するためのメモリを取得するには、あなたが行うことができます:

char words[15][45]; 
//^  ^^ 
// no *  memory for each of the 15 strings 

今、あなたは15個の文字列のメモリを持っています。各文字列は最大44文字です。

この変更では、tmp変数は不要です。ちょうどwordsに直接読み込まれます。以下のような何か:

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

int main (int argc, char* argv[]) 
{ 
    char words[15][45]; 
    int i = 0; 

    FILE* fp = fopen("small", "r"); 
    if (!fp) 
    { 
    printf("no such file\n"); 
    return 0; 
    } 

    while ((i < 15) && (fscanf(fp, "%44s", words[i]) == 1)) 
    {         // ^^^^^^^^ is the same as &words[i][0] 
    i++; 
    } 
    printf("\n"); 

    int t; 
    for (t = 0; t < i; ++t) 
    { 
    printf("Words %d = %s\n", t, words[t]); 
    } 

    fclose(fp); 

    return 0; 
} 

他のいくつかの重要な変更が追加さ:

1)fopenした後、あなたが常に最大サイズを与える%sのscanf関数についてはNULL

2)を確認する必要があります(つまり%の44S)あなたは、バッファオーバーフローを防止するための15個の文字列()

を読んだとき whileを停止することを確認してください)

3バッファオーバーフローがあることはできませんそれは共通の問題である - あなたは

で読んだことがあるよう

4)のみなど、多くの文字列を印刷するには、最後に私は、これはと重複している質問の数が存在しなければならないmain

+0

役立つヒント、多くの感謝! – Leon

関連する問題