dポイントプレゼントキャンペーン実施中!

http://oshiete1.goo.ne.jp/kotaeru.php3?q=2376843
で、質問させて頂いた者です。
先日は大変にお世話になりました。

先日の質問の続きという感じなんですが…

------------------
「ex」ファイルのデータ
41 100000
42 110000
43 120000
---------
これらのデータを
kihokyu[1].tosi=41
kihokyu[1].kan=100000
kihokyu[2].tosi=42
kihokyu[2].kan=110000
という感じで格納したいのです。
------------------------

お陰様で、kihokyu[].tosiの方は
格納する事が出来ました。

ただ、
kihokyu[].kanの方が
格納することが出来ません。
「1245015」という値が
格納されてしまいます。

この原因は
strtokの第一引数にNULL を渡したときの動作を
理解していないのかも知れません。

------------------------

バッファにいったん蓄えて
>buff = "41 100000\n"

41を構造体「kihokyu[i].tosi」に格納
>kihokyu[i].tosi = atoi(strtok(buff , " "));

ここが上手く行かない
10000を構造体「kihokyu[i].kan」に格納したつもり
>kihokyu[i].kan = atoi(strtok(NULL , " \n"));

私の理解では、説明文の方に
>2回目以降の呼び出しでは s1 に NULL を指定します
と、ありましたので
この時点で、NULL変数には
「10000」が蓄えられていると
理解しています。

この認識は間違っているのでしょうか?
ご教示して頂けたら幸いです。

A 回答 (3件)

#include <stdio.h>


#include <stdlib.h>
#include <string.h>

typedef struct nentbl_ {
int tosi;
int kan;
} nentbl;

int main(void){
char buff[16];
FILE *fp;
int i=0;

nentbl kihokyu[50];

fp = fopen("ex.fil","r");
while(fgets(buff,sizeof buff,fp) != NULL){
if ( i == 50 ) break;

kihokyu[i].tosi = atoi(strtok(buff , " "));
kihokyu[i].kan = atoi(strtok(NULL , " \n"));

printf("toshi:%d\n",kihokyu[i].tosi);
printf("kan:%d\n",kihokyu[i].kan);
i++;
}
fclose(fp);
return 0;
}
----------------------------------------------------------------
を試してみてどうなるか、教えていただけますか?
あと、コンパイラは何をお使いでしょうか?
    • good
    • 0
この回答へのお礼

ご回答して頂いたプログラムを
試してみました。

正常に出力されました。

ただ分からないのは
私も同じようなプログラムだと思うのですが
どこがおかしいのか
分からないのです。

それで今日、
私のプログラムを実行してみたところ
正常に出力されるのです。

ちょこまかといじっていたので
その辺りが原因なのかとは思いますが
ハッキリとしないところが気持ち悪いです。

>あと、コンパイラは何をお使いでしょうか?
borlandのbcc32.exe
というのを使用しています。

お礼日時:2006/09/05 10:49

char buff[16];


buff = "41 100000\n";
kihokyu[i].tosi = atoi(strtok(buff , " "));

上記のようにstrtokにリテラルな文字列へのポインタを渡してはいけません。

上記の処理は

kihokyu[i].tosi = atoi(strtok("41 100000\n" , " "));

と同じで、これを実行するとプログラムメモリを壊します。

この後は、メモリが壊れているので何が起きるか判りません。変な所に変な物が格納されたり、暴走したり、フリーズしたりするでしょう。

buff = "41 100000\n";

は「buffに文字列を格納せず、16バイトの作業用メモリを指していたbuffのアドレスを忘れ去り、新たにbuffが文字列定数"41 100000\n"の内部アドレスを指すようにする」って事です。

buffの中に文字列をセットしたいなら

char buff[16];
strcpy(buff,"41 100000\n");
kihokyu[i].tosi = atoi(strtok(buff , " "));

と書かないとなりません。

「ポインタの変更」と「文字列のコピー」は見た目の実行結果は同じですが意味が全然違います。

この回答への補足

ご返事有り難うございました。
お陰様で正常に出力されました。
ただ、幾つか質問したいことがありましたので
お手数かとは思いますが
ご教示して頂けたら幸いです。

1.
>「buffに文字列を格納せず、16バイトの作業用メモリを指していたbuffのアドレスを
>忘れ去り、新たにbuffが文字列定数"41 100000\n"の内部アドレスを指すようにする」
>って事です。
ということは、
buff = "41 100000\n";
とした場合は、
buffに「41 100000\n」というアドレスが
格納されてしまうと理解して宜しいのでしょうか?


2.ファイルのデータから入力をする場合、
以下のようにしないといけないのでしょうか?
------------
二つのバッファ変数を用意して、
char buff[16];
char buff2[16];
FILE *fp;



いったん仮のバッファに入れて、
while(fgets(buff2,sizeof buff2,fp) != NULL){

それから本当のバッファに入れる
strcpy(buff , buff2);

のような感じで
処理をするのでしょうか?


3.もう一つ分からないのは
NO,3で回答して頂いた方の方法でも
正常に処理することが出来たのですが
strcpyを使用した方が良いのでしょうか?


申し訳ありませんが
よろしくお願いします。

補足日時:2006/09/05 11:42
    • good
    • 0

その例だと, 期待通りの結果になると思うんですが, 違いますか?


「どのようなデータに対して」
「どのような結果を期待して」
「どのような (期待に反する) 結果が得られたのか」
を挙げてもらえませんか?
    • good
    • 0
この回答へのお礼

ご返事有り難うございました。

今日実行したところ
期待通りの結果が得られました。

どうしてだろう…

お礼日時:2006/09/05 11:53

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!