2017-04-24 12 views
0

私のプログラムで何が問題なのかはわかりませんが、ファイルを開き、そこから最初の行を読み取り、それを印刷する簡単なコードです。しかし、プログラムはクラッシュし続けます。私のテキストファイルの実際の内容は文章です:私のコードをテストしてください。char *文字列を印刷できません

int main(void) 
{ 
FILE *stream; 
char *s; 
stream = fopen("input.txt", "r"); 
fscanf(stream, " %s", &s); 

printf("%s", s); 


fclose(stream); 
return 0; 
} 

私は<string.h>

+3

1. 'fopen'の結果をチェックしません。 2. 's'は初期化されていないポインタです - データはどこに行きますか? – John3136

+1

'char s [16]; fscanf(ストリーム、 "%s"、&s); ' – BLUEPIXY

+1

GCCを使用している場合、常に' gcc -Wall -Werror'でコンパイルしてください。 。 –

答えて

3

sで見つかったライブラリ関数を使用しないように指示していますが初期化されていないポインタです。書き込みにはfscanfのメモリを割り当てる必要があります。

+0

私はそれを次のように初期化しました:char * s = NULL;しかし、プログラムはまだクラッシュします – user43783

+0

() – aschepler

+0

スタック上のメモリ( 'char s [10]'はスタック上に10文字を割り当てます)またはmallocで動的メモリ割り当てを使用することができます – d3L

0

コードに欠けているものはほとんどありません。

// Uninitialise pointer, you need to allocate memory dynamically with malloc before you use it. That is 
char *s; 
int size = 20; // size of the string you want 
s = malloc(size * sizeof(char)); 

// Or you can use a VLA and with this you don't have to use free(s) 

char s[20]; 


// fopen could fail, always check the return value before using it. 
stream = fopen("input.txt", "r"); 

if(stream == NULL){ 
    perror("File opening failed"); 
     return EXIT_FAILURE; 
} 
fscanf(stream, "%s", s); 


//Don't forget to do free(s) to free memory allocated with malloc . when you are done with it 
0
char *s; 

(ほとんどのシステム32/64ビットで)メモリアドレスを保持するために必要なバイト数を割り当てます。 しかし、ポインタを初期化していないので、その値(のアドレスはになります)は定義されていません。

Ergo:fscanfは、未定義のメモリアドレスに書き込もうとします。

char * s = NULLとして初期化しました。

はい、ポインタは現在初期化されていますが、現在どこにも指していません。

Ergo:fscanfは何も書き込もうとしません。

解決策は、fscanfが使用できるメモリを割り当てることです。 fscanfはあなたのために魔法のようにメモリを割り当てません!

スタックメモリまたは動的割り当てメモリ(ヒープ)を使用できます。

スタックメモリは管理が簡単ですが、ヒープよりもはるかに小さくなっています。ここで

スタック上のメモリを使用するソリューション:私は%9s代わりの%sを使用する理由

// Allocates 10 bytes on the stack 
// Given 1 Character = 1 Byte the 
// buffer can hold up to 9 characters. 
char myBuffer[10]; 

// Initialize s with the address of myBuffer 
char *s = myBuffer; 

// Call fscanf 
fscanf(stream, "%9s", s); 

あなたは不思議に思われるかもしれません。

理由は、バッファオーバーフローを防ぐためです:

関数fscanfは、バッファがどのように大きな認識していないので、あなたはそれを伝える必要があります。

それ以外の場合、fscanfは割り当てられたメモリを超えてデータを書き込みます。

一般的にCの文字列とメモリ管理についてお読みになることをお勧めします。

+1

'fscanf(stream、") '%s'は空白を保存しません '' 1 2 3 "'のような行は '' s ''として読み込まれません2 3 "' – chux

+0

@chuxきちんとした観察。それを知らなかった:) – d3L

関連する問題