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

CSV形式のファイルを読み込んで計算するプログラムを cygwinの環境で、gcc を使って 作っています。
w2kパソコンで作ったプログラムをwin7パソコンで修正したら、うまく動きません。
試行錯誤したところ、数字ー数値変換がおかしいことがわかりました。

w2k の時 strtol、strtod
win7 では、atoi atof
でうまく動作するようになりました。

なんでこのような差が出てくるのか、ご存知の方がいたら教えて下さいませ。

A 回答 (2件)

いくつか気になったので指摘しておきます.



・sscanf(tok, "%08d", &l); のところ, l は long だから %08d ではなく %08ld とすべき... いや, 0 が使えないから %8ld じゃないとダメか.
・printf ("l=%d, m=%d n=%d\n", l); は書式文字列に対して引数が足りない.
・b[i] = strtod (tok, e); の e の値はどうなっていますか?
    • good
    • 0
この回答へのお礼

ご指摘をヒントに e の部分を次のようにいじくったら問題なく動きました。

(異常)
char **e;
値 = strtod (文字列変数, e);

(正常)
char *e;
値 = strtod (文字列変数, &e);

char **e; がダメかというと、そうではなく、検証プログラムを作るとちゃんと動作します。

他のご指摘部、
%08ld は intもlongも32bit長なので実害はなかったです。
正しくはご指摘通りですから修正しましたが動作に違いはありませんでした。

printfの引数は注意不足の間違いでしたので修正しましたが、こちらも動作は同じでした。

何でもかんでも大域変数にする下手なプログラムの不具合が、環境が変わったことで現れたのだと思います。全体を作り直すようにします。
ご指摘を頂いたおかげで、踏ん切りがつきました。ありがとうございました。

お礼日時:2017/05/29 21:32

正直なところ, これではなにが問題なのかさっぱりわからないね.



この文章からすると, win7 では strtol や strtod を使ったときに「正しく」変換できない, ということでいい? だとしたら, 2つの PC で
#include <stdio.h>
#include <stdlib.h>

int main()
{
int x = strtol("12345", 0, 0);
double d = strtod("15.93e6", 0);
printf("x = %d, d = %f\n", x, d);
return 0;
}
というプログラムを実行したらそれぞれどのように表示されますか?

あと, それぞれで gcc のバージョンはどうなっていますか?
    • good
    • 0
この回答へのお礼

つたない質問に回答いただきありがとうございます。
ご理解のとおりです。

今時点は win7 の環境しかないのですが、確認してみました。

いただいたプログラムの結果
$ ./xxx.exe
x = 12345, d = 15930000.000000
問題なく動きました。

$ gcc -dumpversion
5.4.0

私の問題認識が違っていたということですね。
更に、次の確認をしてみました。

プログラム1
int main(){
printf ("01234567,");
for (i=0; i<64; i++) {
printf ("%d,%.2f,", i, (float)i/2);
}
return 0;
}

実際と同じ文字列ー数値変換部

char text[]="プログラム1の実行結果の文字列"
char *tok;
char **e;
int i = 0;
long l;

int a[128];
double b[128];

int main () {
tok = strtok (text, ",");
sscanf(tok, "%08d", &l);
printf ("l=%d, m=%d n=%d\n", l);

while (i<128) {
tok = strtok (NULL, ",");
if (tok == NULL) {
break;
}
a[i] = strtol (tok, NULL, 0);

tok = strtok (NULL, ",");
if (tok == NULL) {
break;
}
b[i] = strtod (tok, e);
printf ("a[%d]=%d, b[%d]=%f\n", i, a[i], i, b[i]);
i++;
}
return 0;
}

実行結果

$ ./xxx
l=1234567
a[0]=0, b[0]=0.000000

: 中略

a[63]=63, b[63]=31.500000

これも問題ありませんでした。

という事は、文字列が正常なら問題なく動作するわけで、
ポインタや変数を壊している場所がないか、再々確認してみます。
ご指摘ありがとうございました。

お礼日時:2017/05/28 17:31

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