🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

5回答

3022閲覧

test.batに書いてある変数Seenの値を読み込んで変数Seenの値を変える。

R-ogiura

総合スコア60

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

1クリップ

投稿2019/11/05 23:41

編集2019/11/06 16:37

前提・実現したいこと

同じフォルダに入っているtest.batに書いてある変数の値をキースペースを押したときに読み込みたいのですがうまくいきません。あと何を付け足せばいいのでしょうか。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

if (Key[KEY_INPUT_SPACE] == 1) { FILE* fp; char filename[] = "test.bat"; int buf_w[1], buf_r[1]; int i; tai = 0; for (i = 0; i < 1; i++) buf_w[i] = (i + 1); if (!(fp = fopen(filename, "wb"))) return; if (fwrite(buf_w, sizeof(int), 1, fp) != 1) { fclose(fp); return; } fclose(fp); if (!(fp = fopen(filename, "rb"))) return; if (fwrite(buf_r, sizeof(int), 1, fp) != 1) { fclose(fp); return; } fclose(fp); Seen = buf_r[i];//batファイルの一行目に読み込んだ値を変数Seenに代入する

試したこと

debugを行うと変数iは‐1でした。0に設定したはずなのになぜでしょうか。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

編集
あの後以下のように書き直しました。

if (Key[KEY_INPUT_SPACE] == 1) { if (!(fp = fopen(filename, "rb"))) return; if (fwrite(buf_r, sizeof(int), 1, fp) != 1) { fclose(fp); return; } fclose(fp); Seen = buf_r[yomikomi]; }

test.batの中身は数値の8です。
変数iは名前をyomikomiに変えました。実行時の値はyomikomiもbuf_r[yomikomi]も0です。
また初期化のためにint buf_r[1] = { 0 };と書きましたが「初期化されていないメモリbuf_rを使っていますと言われます。

FILE* fp; char filename[] = "test.bat"; int buf_r[1] = { 0 }; int yomikomi = 0;

実行ファイルを開き、スペースキーを押しましたところyomikomiもbuf_r[yomikomi]も0のままで、変数Seenも0のままです。

編集2

if (Key[KEY_INPUT_SPACE] == 1) { if (!(fp = fopen(filename, "rb"))) return; if (fread(buf_r, sizeof(int), 1, fp) != 1) { fclose(fp); return; } fclose(fp); Seen = buf_r[yomikomi]; } }

のように書き直し、バッチファイルの内容は

Seen = 8;

と書きました。実行してスペースキーを押すとSeenの値が変化しました。
しかし8に変化したのではなく、とんでもなく大きな数値1852138835に変化しました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Y.H.

2019/11/06 00:01

> test.batに書いてある変数の値 test.batを質問に記載ください。 また、質問記載のプログラムを実行し、test.batをで読み込んだ際に、どういう値を取得したいのか 具体例を質問に記載ください。
R-ogiura

2019/11/06 00:13

明記させて頂きました。
Y.H.

2019/11/06 00:15

> test.batの中身は数値の8です え?!test.batは1文字8だけですか? 変数は?batなのでバッチファイルだと思い、以下のように書かれているのかと思ってました。 [TOF - test.bat] @echo off set val=8 [EOF]
R-ogiura

2019/11/06 00:25 編集

バッチファイルには「Seen = 8;」と書いていました。 読み込んだ際に変数Seenに8を代入したいため、「Seen = 8;」と書きました。
R-ogiura

2019/11/06 00:41

Seen = 8と書きなおしましたが、その場合でもスペースキーを押すと変数Seenがとんでもなく大きな値になります。
dodox86

2019/11/06 00:52

「バッチファイル」と聞くとWindowsユーザーやプログラマーにとってはコマンドプロンプト(CMD.EXE)のようなコマンドプロセッサーで動作させる*.BATや*.CMDファイルを想起するのですが、本質問にとっては、その範囲外のことなのでしょうか。(DXライブラリ絡みだとしても、謎です)
Zuishin

2019/11/07 06:59

おやこれは carnage0216 さんではありませんか。
episteme

2019/11/07 07:38 編集

複数IDの保有は禁じられているので 「よほどの阿呆か不届き者でないかぎり」 それはないかと。
R-ogiura

2019/11/07 07:37

そういう人もいるんですね。気を付けないとです!
Zuishin

2019/11/07 08:06

確かに、もし同じ人だとしたらよほどの阿呆で不届き者ですね。 carnage0216 という人は自分で自分のことを過大評価しすぎているのか、何度もバレバレの三文芝居を繰り返してる道化ですが、さすがにまたやったとしたら、もうどうしようもない弩級の阿呆と言わざるを得ません。ちょっと手加減なしでかわいがってあげたくなりますね。
episteme

2019/11/07 08:21

ところでR-ogiuraさん、あなたのプロフィールに貼られたリンクは何かの間違いですか?
R-ogiura

2019/11/07 09:43

間違いではないですね。ある方から張るように言われました。 特に理由はわかりませんでしたが張っても問題なさそうな内容だったので張りました。
Zuishin

2019/11/07 09:45

問題ないとなぜ思ったのかわかりませんが、ここで質問せずそのある方に聞けばいいんじゃないですかね。
thkana

2019/11/07 09:53

気を付け'だいと'です、なんつって、ね。
R-ogiura

2019/11/07 09:57

気を付け'ナイト'です、なんつって、ね。
Zuishin

2019/11/07 10:18

なぜそのある方に聞かないんでしょうか? そこに書いてあるエピステーメーが誰のことかわからないわけではないでしょう?
Zuishin

2019/11/07 10:27

黙殺ということは、わかっていてわざと喧嘩を売っているようですね。
episteme

2019/11/07 11:14 編集

R-ogiuraさんは僕に敵意があると見做してよろしいですか? そうであるならそれ相応の対応を致しますし、 そうでなければ僕個人的には甚だ不愉快なので消してもらえると有難いです。
R-ogiura

2019/11/07 11:26

張ったものはそんなにやばい物なのでしょうか!? 誰が誰に対して何を言っているかさっぱりわからなかったので張ったのですが、、、
Zuishin

2019/11/07 11:27

そこまで愚かなのですか? carnage0216 さんと同レベルではありませんか。
episteme

2019/11/07 11:30 編集

「誰が誰に対して何を言っているかさっぱりわからなかった」のなら 僕個人的には甚だ不愉快なので消してもらえると有難いです。 # あなた、"さっぱりわからん"ものをプロフィールに書くんですか?
R-ogiura

2019/11/07 11:30

わかりました。
episteme

2019/11/07 12:08

なにに対して「わかりました。」か?
R-ogiura

2019/11/07 13:50

この記事はそんなにやましい物なのでしょうか? そんなに必死になるということは事実である可能性もあるため消しにくいですね。
episteme

2019/11/07 18:51 編集

ではあなたには"しかるべく"接します。 で、なにに対して「わかりました。」か?
episteme

2019/11/07 17:17

なにに対して「わかりました。」なのですか?
guest

回答5

0

なんというか,もっとこう,
「自分が決めたファイルのフォーマットに対して,それに見合った読込処理を実装するのだ」
という強い意志を持って実装を考えるべきではないでしょうか.

  • そのファイルはテキストモードとバイナリモードのどちらで扱う想定なのか?
  • Seen = 8; みたいな記述が,ファイルのどこかに書かれている(かもしれない)という代物なのか,それともファイルの特定の位置(「n行目」とか「nバイト目」とか)に必ずSeenの値に関する記述が存在する前提なのか?
  • Seen = 8;をパースして「Seen に 8 を代入するのだ」という解釈を行う必要があるのか?

それとも,Seen = 部分や最後のセミコロンは単なる飾り(!?)なのか.
=の前後の空白の個数等は任意なのか?それもきっちりフォーマットで定めた個数であるべきなのか?

  • あと,なぜ「バッチファイル」なのか?

例えば,(私なら,ですが)
最初からテキストモードを想定していれば,"rb"とか"wb"とか"fread"とか"fwrite"とかを適当に書いて「うまく読めない」とか言うような事態に至らないと思うし,
バイナリモードを想定していれば,そんなスクリプトチックな記述のファイルにしてわざわざ読込難易度を上げたりしないよなぁ,とか思うのです.

ファイル読込処理に慣れてないなら,最初は自身が最も簡単に読込できる(できそうな)形態を考えてはどうでしょうか.
内容が 8 だけのテキストファイルとか,あるいは4byteのバイナリとかじゃダメなんでしょうか?
(仮にそれだと今作っている物に対しては不足なのだとしても,とりあえず練習として,最初はそういう簡単なのを読み書きしてみる,という段階を経た方が良いように見受けます)

投稿2019/11/07 02:31

fana

総合スコア11990

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/11/07 02:55

1. 何をしたいのか 2. (1)に相応しい設計か 3. (2)に忠実な実装か たぶん(1)すらあやふやなんじゃなかろうか。
guest

0

fwriteしてるからでは。
freadしないと。

投稿2019/11/06 00:13

ttyp03

総合スコア17000

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

R-ogiura

2019/11/06 00:50

そうでした! どうもありがとうございます!
guest

0

ベストアンサー

fscanf を使えば簡単です。

C

1#include <stdio.h> 2 3int main(void) 4{ 5 FILE *fp = fopen("test.bat", "r"); 6 if (!fp) return 1; 7 int seen; 8 if (fscanf(fp, " Seen =%d", &seen) != 1) return 2; 9 fclose(fp); 10 printf("seen = %d\n", seen); 11}

投稿2019/11/06 08:22

kazuma-s

総合スコア8224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

R-ogiura

2019/11/07 10:12

FILE* fp = fopen("test.dat", "r"); if (!fp) return 1; int Seen; if (fscanf(fp, " Seen =%d", &Seen) != 1) return 2; fclose(fp); printf("Seen = %d\n", Seen); 変数Seenが小文字のseenになっている部分を直して、test.batをtest.datにして使わせて頂きましたがSeenは0のままでした。
R-ogiura

2019/11/07 10:18

の前に書いてあったint Seen = 0;を消して、後は先ほど書いたように修正したところちゃんと機能しました。 本当にどうもありがとうございます! FILE* fp = fopen("test.dat", "r"); if (!fp) return 1; int seen; if (fscanf(fp, " Seen =%d", &Seen) != 1) return 2; fclose(fp); printf("Seen = %d\n", Seen);
R-ogiura

2019/11/07 10:35

あのどう修復すれば 最初に書いた if (Key[KEY_INPUT_SPACE] == 1) { if (!(fp = fopen(filename, "rb"))) return; if (fwrite(buf_r, sizeof(int), 1, fp) != 1) { fclose(fp); return; } fclose(fp); Seen = buf_r[yomikomi]; } を利用することが出来ますか?
episteme

2019/11/07 12:04 編集

↑いやこの回答そのまんまでしょう。 テキストモードでfopenしてfscanfすればいい。 # 今一度書籍やサイトなどで基礎をしっかりと学ぶ必要があります
R-ogiura

2019/11/07 13:34

C言語の絵本のサンプルを用いて今回のようなファイルを操作するプログラムを書いたのですが、基礎の本を読んでいるんですが、どうもうまく学習できなくて。 FILE* fp; fp = fopen("test.dat", "wb"); buf_w[1] = 8; if (!(fp = fopen(filename, "wb"))) return 0; if (fwrite(buf_w, sizeof(int), 1, fp) != 1) { fclose(fp); return 0; } と書いてみましたが、datファイルには何も書き込めていませんでした。
R-ogiura

2019/11/07 13:46

前に書いてあったint Seen = 0;とint Seenを消して、後は先ほど書いたように修正したところちゃんと機能しました。 FILE* fp = fopen("test.dat", "r"); if (!fp) return 1; if (fscanf(fp, " Seen =%d", &Seen) != 1) return 2; fclose(fp); printf("Seen = %d\n", Seen);
R-ogiura

2019/11/08 00:39

本に記載された通り、質問に載せたプログラムのみを実行させたところ文字化けした数値しか出力されず、kazuma-sのプログラムでは正しくでるので、本のサイトのプログラムと組み合わせてほんのサンプルが正しく合わせられるように直せました。 どうもありがとうございます! #include<stdio.h> #pragma warning(disable: 4996) void main(void) { char filename[] = "test.dat"; int buf_r[10], buf_w[10],Seen; int i; for (i = 0; i < 10; i++) buf_w[i] = (i + 1) * 10; FILE* file; // ファイルポインタ(出力用) file = fopen("test.dat", "wb"); // ファイルを書き込み用にオープン(開く) if (file == NULL) { // オープンに失敗した場合 printf("ファイルが開けません。¥n"); // エラーメッセージを出して //exit(1); // 異常終了 } // ファイルにデータを書き込む for (i = 0; i < 10; i++) { fprintf(file, "buf_w[%d] = %d\n", i,buf_w[i]); // ファイルに書く } fclose(file); // ファイルをクローズ(閉じる) FILE* fp = fopen("test.dat", "rb"); if (!fp) return ; for (i = 0; i < 10; i++) { if (fscanf(fp, " buf_w[%d] =%d", &i, &buf_w[i]) != 1) ; } for (i = 0; i < 10; i++) { printf("buf_w[%d] = %d\n", i, buf_w[i]); } fclose(fp); }
guest

0

テキストファイルをバイナリ・オープンし、ファイルの"先頭4バイト"を読んでint変数にねじこむ...が、あなたのやりたいことですか?コードはそんなことやって、そのとおりに動いています。

投稿2019/11/06 02:59

編集2019/11/06 03:03
episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

episteme

2019/11/06 07:41

#define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { FILE* fp; int Seen = 0; fp = fopen("test.bat","rt"); if (fp != NULL) { char line[256]; fgets(line,256,fp); // 1行をlineに読み込む fclose(fp); const char* p = strchr(line, '='); //'=' を見つけたら、それ以降の文字列をintに変換してSeenにセット if ( p != NULL ) { Seen = atoi(p + 1); } } printf("Seen = %d\n", Seen); return 0; } こんなことしたかったんかな?
R-ogiura

2019/11/07 06:44

知らない人のURLを付けて人聞きの悪いことを言わないでください。
R-ogiura

2019/11/07 07:37

こちらのプログラムはSeenの値を読み込みますが、そのあとの読み込んだSeenの値を変数Seenに代入したいのですが、それは出来るのでしょうか。 実行してスペースキーを押しても変数Seenが0のままで値が代入されませんでした。
episteme

2019/11/07 08:03

「こちらのプログラム」とはどれのことですか? このコメント欄に僕が置いたコードは、ファイルから読んでSeenに格納しています。
R-ogiura

2019/11/07 09:36

ファルダに中身を「Seen = 8;」と書いたtest.batを用意したのですが、なぜか読み込んでくれず、スペースキーを押してもSeenは0のままなのです。
Y.H.

2019/11/07 09:46

> 中身を「Seen = 8;」 中身は全部半角で書きましょう。
R-ogiura

2019/11/07 10:21

どうもありがとうございます。 epistemeさんの載せて頂いたプログラムに関しては int Seen = 0;とreturn 0;を消して、test.batをtest.datとしたら機能しました。 どうもありがとうございます。
guest

0

if (!(fp = fopen(filename, "wb")))

これでいきなりtest.batの内容を消去してしまってます
また、どーみても、ファイルから読み込んでません。
そもそもの作りを見直しましょう

投稿2019/11/05 23:47

y_waiwai

総合スコア88040

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

R-ogiura

2019/11/06 00:50 編集

指摘、ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問