scriptファイルの開き方

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
THムラオサ
記事: 17
登録日時: 9年前

scriptファイルの開き方

#1

投稿記事 by THムラオサ » 9年前

新年明けましておめでとうございます。
新年早々に申し訳ないのですが、タイトルにあるようにscriptファイルを開くということなのですが、エラーがおきて実行できませんでした。 

このエラーを消すにはどうすればいいのでしょうか。
それとテキストファイルの場所はあっていますか。

この2つのご解答お願いします。

エラーは下記のものです。
警告 2 warning C4129: ' ' : エスケープ シーケンスとして正しく認識されませんでした。 c:\users\user\documents\visual studio 2013\projects\script\script\script01.cpp 33 1 script

エラー 1 error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details. c:\users\user\documents\visual studio 2013\projects\script\script\script01.cpp 30 1 script


scriptファイル場所は下記のとこにあります。

GameProg_2012  →    GameProg_2012 →  fp(テキストのファイル名です)



コードは下記のものです。

コード:


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

 //スクリプトは最大1000 行まで読み込む
 #define SCRIPT_MAX_LINE 1000
 //スクリプト最大文字数
 #define SCRIPT_MAX_STRING_LENGTH 300

 typedef struct ScriptInformation_tag {
	 int maxLineNumber; //スクリプト行数
	 int currentLine; //現在何行目を実行しているか
	 const char* filename; //ファイル名
	 char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
	
} ScriptInformation;

 //スクリプトファイルを読み込む
 //戻り値-1 : 失敗0 : 成功
 int loadScript(const char* filename, ScriptInformation* scriptInfo)
 {
	 int  pos;
	 char c;
	 //スクリプトファイル
		 FILE* fp;
	
		 //スクリプト情報を初期化
		 memset(scriptInfo, 0, sizeof(ScriptInformation));
	
		 //スクリプトファイルを開く
		 fp = fopen(filename, "r");
	 if (fp == NULL) {
		 //ファイル読み込みに失敗
			 printf("スクリプト%s を読み込めませんでした\ n", filename);
		 return -1;
		
	}
	
		 // s c r i p t 書き込み時に使用
		 pos = 0;
	
		 for (;;) {
		 //一文字読み込み
			 c = fgetc(fp);
		 //ファイルの終わりかどうか
			 if (feof(fp)) {
			 break;
			
		}
		
			 if (pos >= SCRIPT_MAX_STRING_LENGTH - 1) {
			 //1 行の文字数が多すぎる
				 printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
			 return -1;
			
		}
		
			 //改行文字が出てきた場合,次の行へ移動
			 if (c == '\n') {
			 //\0 を文字列の最後に付ける

				 scriptInfo->script[scriptInfo->currentLine][pos] = '\0';
				  //次の行に移動
					  scriptInfo->currentLine++;
				  //書き込み位置を0 にする
					  pos = 0;
				 
			 }
			 else {
				  //書き込み
					  scriptInfo->script[scriptInfo->currentLine][pos] = c;
				  //文字書き込み位置をずらす
					  pos++;
				 
			 }
			 
		 }
		  //最大行数
			  scriptInfo->maxLineNumber = scriptInfo->currentLine;
		 //読み込み中の行を0 にする
			  scriptInfo->currentLine = 0;
		  //スクリプトファイル名を設定
			 scriptInfo->filename = filename;
		  return 0;
		  }
		 
			  int main()
			  {
			  int i;
			  ScriptInformation script;
			 
				  loadScript("./script.txt", &script);
			 
				  //10 行目までを表示
				  for (i = 0; i < 10; i++) {
				  printf("%d : %s\n", i + 1, script.script[i]);
				 
			 }
			 
				  return 0;
			  }


アバター
little
記事: 44
登録日時: 13年前
連絡を取る:

Re: scriptファイルの開き方

#2

投稿記事 by little » 9年前

THムラオサ さんが書きました:このエラーを消すにはどうすればいいのでしょうか。
警告 2 warning C4129: ' ' : エスケープ シーケンスとして正しく認識されませんでした。

34行目

コード:

printf("スクリプト%s を読み込めませんでした\ n", filename);
nの前のスペースを消します。

2件目がこっちでは確認できませんが、53行目

コード:

printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
dの前のスペースを消すといいと思います。
THムラオサ さんが書きました:エラー 1 error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

コード:

この関数や変数が安全でない可能性があります。代わりにfopen_sを使用することを検討してください。
非推奨を無効にするには、_CRT_SECURE_NO_WARNINGSを使用します。
google翻訳より
要訳の通り、fopen_sを使用する又は_CRT_SECURE_NO_WARNINGSを使用することで改善されます。
※VC2010ではエラーになりませんが、VC2012以降?ではデフォルト設定でエラー扱いのようです。

THムラオサ さんが書きました:それとテキストファイルの場所はあっていますか。
scriptファイル場所は下記のとこにあります。
GameProg_2012  →    GameProg_2012 →  fp(テキストのファイル名です)

確かカレントディレクトリからの相対パス指定で行けるはずなので。
► スポイラーを表示
"./script.txt"ということは"script.txt"と同じなので、上記を実行して表示された階層の直下にファイルが有ると合っていると思います。
百聞は~

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#3

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます
おかげで以下のエラーを解決することができました。

コード:

printf("スクリプト%s を読み込めませんでした\ n", filename);

コード:

printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
ですが以下のエラーは下記のコードに直しても改善できませんでした。

エラーについて
エラー 1 error C4996: 'fopen': This function or variable may be unsafe. Consider using fopen_s instead. To disable deprecation, use _CRT_SECURE_NO_WARNINGS. See online help for details.

コード

コード:

 fp = fopen_s(filename, "fp");
_Sにしたらまた違うエラーが出てしました

エラーについて

4 IntelliSense: 関数呼び出しの引数が少なすぎます c:\Users\user\Documents\Visual Studio 2013\Projects\script\script\script01.cpp 30 31 script


3 IntelliSense: 型 "const char *" の引数は型 "FILE **" のパラメーターと互換性がありません c:\Users\user\Documents\Visual Studio 2013\Projects\script\script\script01.cpp 30 17 script


2 IntelliSense: 型 "errno_t" の値を型 "FILE *" のエンティティに割り当てることはできません c:\Users\user\Documents\Visual Studio 2013\Projects\script\script\script01.cpp 30 7 script

というものでした。
 これを改善すればどうすればいいのでしょうか お手数ですが、再びご解答お願いします。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: scriptファイルの開き方

#4

投稿記事 by みけCAT » 9年前

THムラオサ さんが書きました: 4 IntelliSense: 関数呼び出しの引数が少なすぎます c:\Users\user\Documents\Visual Studio 2013\Projects\script\script\script01.cpp 30 31 script


3 IntelliSense: 型 "const char *" の引数は型 "FILE **" のパラメーターと互換性がありません c:\Users\user\Documents\Visual Studio 2013\Projects\script\script\script01.cpp 30 17 script


2 IntelliSense: 型 "errno_t" の値を型 "FILE *" のエンティティに割り当てることはできません c:\Users\user\Documents\Visual Studio 2013\Projects\script\script\script01.cpp 30 7 script

というものでした。
 これを改善すればどうすればいいのでしょうか お手数ですが、再びご解答お願いします。
リファレンスを見てfopen_sを正しく使うか、
コンパイラをGCCなどに乗り換え、fopenのままのコードをコンパイルすればいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: scriptファイルの開き方

#5

投稿記事 by かずま » 9年前

THムラオサ さんが書きました: おかげで以下のエラーを解決することができました。

コード:

printf("スクリプト%s を読み込めませんでした\ n", filename);

コード:

printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
"\n" は、エラーメッセージの通り、エスケープシーケンスですが、
"% d" は、printf の書式であり、エスケープシーケンスではなく、エラーでもありません。

コード:

"%d"   正の符号を表示しない
"% d"  正の符号として、スペースを表示する
"%+d"  正の符号として、+ を表示する

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#6

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます。
みけCATさんご解答して頂いた
 リファレンスを見てfopen_sを正しく使う
 コンパイラをGCCなどに乗り換え、fopenのままのコードをコンパイルする
というのが難しくて理解できませんでした。
fopen_sを正しく使うとはどのようにコードをかけばいいのでしょうか。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: scriptファイルの開き方

#7

投稿記事 by みけCAT » 9年前

THムラオサ さんが書きました:fopen_sを正しく使うとはどのようにコードをかけばいいのでしょうか。

コード:

fp = fopen(filename, "r");
をそのまま置き換えるなら、

コード:

if(fopen_s(&fp, filename, "r") != 0) fp = NULL;
とすればいいと思います。
(こうしなければいけないとは言ってない)
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: scriptファイルの開き方

#8

投稿記事 by みけCAT » 9年前

気になったのですが、
THムラオサ さんが書きました:

コード:

 fp = fopen_s(filename, "fp");
どうして(どう考えて)第二引数を"fp"にしたのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

かずま

Re: scriptファイルの開き方

#9

投稿記事 by かずま » 9年前

エラーメッセージにある通り、#define _CRT_SECURE_NO_WARNINGS
をファイルの先頭に置くだけで、エラーにならずに、fopen が使えるはずです。
ファイルの先頭でなくても、#include <stdio.h> の前ならどこでもいいでしょう。

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#10

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます。
皆様の貴重なお時間を割いて考え答えていただき感謝でいっぱいであります!

みけCATさんの

コード:

if(fopen_s(&fp, filename, "r") != 0) fp = NULL;
かずまさんの

コード:

#define _CRT_SECURE_NO_WARNINGS
などを実装したことにより実行することができました。

最後の質問になるかと思います 実行できたのはいいのですがスクリプトが読みこないため開けません。

プログラム部分でいうと下記のものになります。

コード:

if (fp == NULL) {
		//ファイル読み込みに失敗
		printf("スクリプト%s を読み込めませんでした\n", filename);
		return -1;


visual studioのエラーにはこのように書かれていました

コード:

'script.exe' (Win32): 'C:\Users\user\Documents\Visual Studio 2013\Projects\script\Debug\script.exe' が読み込まれました。シンボルが読み込まれました。
'script.exe' (Win32): 'C:\Windows\System32\ntdll.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
'script.exe' (Win32): 'C:\Windows\System32\kernel32.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
'script.exe' (Win32): 'C:\Windows\System32\KernelBase.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
'script.exe' (Win32): 'C:\Windows\System32\msvcr120d.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
プログラム '[4468] script.exe' はコード 0 (0x0) で終了しました。
どのように改善すれば.txtファイル(fp)が読み込めるのでしょうか


現状のプログラムをお見せします。

コード:

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

 //スクリプトは最大1000 行まで読み込む
#define _CRT_SECURE_NO_WARNINGS

#define SCRIPT_MAX_LINE 1000
 //スクリプト最大文字数
 #define SCRIPT_MAX_STRING_LENGTH 300

 typedef struct ScriptInformation_tag {
	 int maxLineNumber; //スクリプト行数
	 int currentLine; //現在何行目を実行しているか
	 const char* filename; //ファイル名
	 char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
	
} ScriptInformation;

 //スクリプトファイルを読み込む
 //戻り値-1 : 失敗0 : 成功
 int loadScript(const char* filename, ScriptInformation* scriptInfo)
 {
	 int  pos;
	 char c;
	 //スクリプトファイル
		 FILE* fp;
	
		 //スクリプト情報を初期化
		 memset(scriptInfo, 0, sizeof(ScriptInformation));
	
		 //スクリプトファイルを開く
		 if (fopen_s(&fp, filename, "r") != 0) fp = NULL;

		 
	 if (fp == NULL) {
		 //ファイル読み込みに失敗
			 printf("スクリプト%s を読み込めませんでした\n", filename);
		 return -1;
		
	}
	
		 // s c r i p t 書き込み時に使用
		 pos = 0;
	
		 for (;;) {
		 //一文字読み込み
			 c = fgetc(fp);
		 //ファイルの終わりかどうか
			 if (feof(fp)) {
			 break;
			
		}
		
			 if (pos >= SCRIPT_MAX_STRING_LENGTH - 1) {
			 //1 行の文字数が多すぎる
				 printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
			 return -1;
			
		}
		
			 //改行文字が出てきた場合,次の行へ移動
			 if (c == '\n') {
			 //\0 を文字列の最後に付ける

				 scriptInfo->script[scriptInfo->currentLine][pos] = '\0';
				  //次の行に移動
					  scriptInfo->currentLine++;
				  //書き込み位置を0 にする
					  pos = 0;
				 
			 }
			 else {
				  //書き込み
					  scriptInfo->script[scriptInfo->currentLine][pos] = c;
				  //文字書き込み位置をずらす
					  pos++;
				 
			 }
			 
		 }
		  //最大行数
			  scriptInfo->maxLineNumber = scriptInfo->currentLine;
		 //読み込み中の行を0 にする
			  scriptInfo->currentLine = 0;
		  //スクリプトファイル名を設定
			 scriptInfo->filename = filename;
		  return 0;
		  }
		 
			  int main()
			  {
			  int i;
			  ScriptInformation script;
			 
				  loadScript("./script.txt", &script);
			 
				  //10 行目までを表示
				  for (i = 0; i < 10; i++) {
				  printf("%d : %s\n", i + 1, script.script[i]);
				 
			 }
			 
				  return 0;
			  }


YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: scriptファイルの開き方

#11

投稿記事 by YuO » 9年前

THムラオサ さんが書きました:最後の質問になるかと思います 実行できたのはいいのですがスクリプトが読みこないため開けません。
プログラム部分でいうと下記のものになります。

コード:

if (fp == NULL) {
		//ファイル読み込みに失敗
		printf("スクリプト%s を読み込めませんでした\n", filename);
		return -1;
まず,fopen_sは失敗するとエラーコードを返します。
そのエラーコードは何ですか。また,strerrorなりstrerror_sなりを使って文字列化した場合の,エラーメッセージは何ですか。

なんとなく,ファイルがそもそも存在しないという可能性が高そうですが。
システムが利用するファイルは,相対パスではなく,実行ファイル名等を元に絶対パスに変換して指定します。
とくに,カレントディレクトリなどという信用できないディレクトリからの相対パスは,
自分が想定しているディレクトリと違うディレクトリがカレントであるのが当然という前提で作る必要があります。

THムラオサ さんが書きました:visual studioのエラーにはこのように書かれていました

コード:

'script.exe' (Win32): 'C:\Users\user\Documents\Visual Studio 2013\Projects\script\Debug\script.exe' が読み込まれました。シンボルが読み込まれました。
'script.exe' (Win32): 'C:\Windows\System32\ntdll.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
'script.exe' (Win32): 'C:\Windows\System32\kernel32.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
'script.exe' (Win32): 'C:\Windows\System32\KernelBase.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
'script.exe' (Win32): 'C:\Windows\System32\msvcr120d.dll' が読み込まれました。PDB ファイルを開けないか、ファイルが見つかりません。
プログラム '[4468] script.exe' はコード 0 (0x0) で終了しました。
これは出力ペインにあるデバッグ用の情報です。
自作DLLのデバッグも行っているような場合にPDBファイルが開けないというノであれば別ですが,
システムのPDBファイルに関する情報は単純に無視しても問題ありません (通常デバッグ情報なんてないし,デバッグもしないから)。

かずま

Re: scriptファイルの開き方

#12

投稿記事 by かずま » 9年前

THムラオサ さんが書きました:どのように改善すれば.txtファイル(fp)が読み込めるのでしょうか
script.txt はどこにありますか?
C:\Users\user\Documents\Visual Studio 2013\Projects\script\ にありますか?

インデントが無茶苦茶で見にくいので書き直しました。
fopen_s ではなく、fopen を使いました。
#define _CRT_SECURE_NO_WARNINGS は、ファイルの先頭(#include <stdio.h>の前) に置かないとだめです。

コード:

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

#define SCRIPT_MAX_LINE 1000            //スクリプトは最大1000 行まで
#define SCRIPT_MAX_STRING_LENGTH 300    //スクリプト最大文字数

typedef struct ScriptInformation_tag {
    int maxLineNumber;                  //スクリプト行数
    int currentLine;                    //現在何行目を実行しているか
    const char *filename;               //ファイル名
    char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
} ScriptInformation;

//スクリプトファイルを読み込む; 戻り値 -1:失敗, 0:成功
int loadScript(const char *filename, ScriptInformation * scriptInfo)
{
    int pos;
    char c;
    FILE *fp; //スクリプトファイル

    memset(scriptInfo, 0, sizeof(ScriptInformation)); //スクリプト情報を初期化
    fp = fopen(filename, "r");          //スクリプトファイルを開く
    if (fp == NULL) {
        printf("スクリプト%s を読み込めませんでした\n", filename);
        return -1;
    }
    pos = 0;                            // script 書き込み時に使用
    for (;;) {
        c = fgetc(fp);                  //一文字読み込み
        if (c == EOF) {                 //ファイルの終わりかどうか
            break;
        }
        if (pos >= SCRIPT_MAX_STRING_LENGTH - 1) {
            printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
            return -1;
        }
        if (c == '\n') {                //改行文字が出てきた場合
            scriptInfo->script[scriptInfo->currentLine][pos] = '\0';
            scriptInfo->currentLine++;  //次の行に移動
            pos = 0;                    //書き込み位置を0 にする
        }
        else {
            scriptInfo->script[scriptInfo->currentLine][pos] = c;
            pos++;                      //文字書き込み位置をずらす
        }
    }
    scriptInfo->maxLineNumber = scriptInfo->currentLine; //最大行数
    scriptInfo->currentLine = 0;        //読み込み中の行を 0 にする
    scriptInfo->filename = filename;    //スクリプトファイル名を設定
    return 0;
}

int main(void)
{
    int i;
    ScriptInformation script;
    loadScript("./script.txt", &script);
    for (i = 0; i < 10; i++) {          //10 行目までを表示
        printf("%d : %s\n", i + 1, script.script[i]);
    }
    return 0;
}

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#13

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます。

まずはじめに、ソースの改善ありがとうございます。
次に、fpファイルの場所についてです。

ローカルディスク(C)→users→user→マイドキュメント→visual studio 2013→projects→project12→fp
にあります。
prpject12というのはfpファイルを開くファイルが書かれているソースのところです。

この場所では開けないのですが、また違う場所になるのでしょうか。

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: scriptファイルの開き方

#14

投稿記事 by YuO » 9年前

THムラオサ さんが書きました:次に、fpファイルの場所についてです。
fpファイルとは何ですか。
THムラオサ さんが書きました:ローカルディスク(C)→users→user→マイドキュメント→visual studio 2013→projects→project12→fp
にあります。
prpject12というのはfpファイルを開くファイルが書かれているソースのところです。
で,実行時のカレントディレクトリ (作業フォルダー) はどこですか。
プログラムを見る限り,カレントディレクトリからの相対パスでファイル名が指定されています。
このため,提示されているプログラムではカレントディレクトリと開こうとしているファイル (script.txt) の相対的な位置関係が問題になるのであって,ファイルの絶対パスは関係しません。

fopenまたはfopen_sが失敗し,errno (fopen) または戻り値 (fopen_s) がENOENTであれば,まずは相対パスではなく絶対パスでファイルを指定してみるとよいでしょう。
ENOENTでないなら,これをする意味はほぼないので,エラー値にあわせた対策をとる必要がありますが。

かずま

Re: scriptファイルの開き方

#15

投稿記事 by かずま » 9年前

THムラオサ さんが書きました: 次に、fpファイルの場所についてです。

ローカルディスク(C)→users→user→マイドキュメント→visual studio 2013→projects→project12→fp
にあります。
main を次のよう変えたらどうなりますか?

コード:

int main(void)
{
    int i;
    ScriptInformation script;

    if (loadScript("c:/users/user/documents/visual studio 2013/projects/project12/fp", &script) != 0) {
		return 1;
	}
    for (i = 0; i < 10; i++) {          //10 行目までを表示
        printf("%d : %s\n", i + 1, script.script[i]);
    }
    return 0;
}
最初の質問では、scriptファイルは、GameProg_2012 の下にあると書いていましたよね。
しかし、今は project12 の下。

エラーメッセージから、プロジェクト名は script かと思ったら、今は project12。

最初の質問のプログラムや、No.10 のプログラムで、loadScript("./script.txt", &script);
と書いてあるから、スクリプトファイルのファイル名は "script.txt" であり、
fp は、プログラムの中で FILE* fp; と宣言された変数で、fopen() により、"script.txt"
に対応付けられたものだと誰でも思いますよ。

プロジェクト名は、script、それとも project12、GameProg_2012 ?
スクリプトファイル名は、"script.txt" それとも "fp" ?

質問があいまいだったり、途中で変えたのかどうか分かりませんが、これでは回答に困ります。

プログラムのインデントは何のためにあるのかわかりますか?
関数定義の始まりと終わり、if文の始まりと終わり、for文の始まりと終わりなどを明確にして
プログラムを読みやすくするためにあるんですよ。

fopen し、fgetc でファイルの最後まで読み終えたら、fclose した方がいいですよ。
fclose しなくても、プログラム終了時に勝手にやってはくれますが。

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#16

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます。

私のいい加減さで皆さんを混乱させてしまって申し訳ございませんでした。

初めに今回の質問を整理させていただきます。
ノベルゲームの制作で「ゲーム作りで学ぶ!実践的C言語プログラミング」というサイトを使用し、作っている最中です。下記のURLのを参考に制作中です。 

http://www.usamimi.info/~guiprog/game/



URL内の第9章 ノベルゲーム用スクリプト言語の作成 ◾スクリプトを読み込む
という内容が今回のプログラムとなります。

まだ私自身もプログラムを理解をしてないことより、質問当初に「fpファイルはscriptファイル場所は下記のとこにあります。

GameProg_2012  →    GameProg_2012 →  fp(テキストのファイル名です)



と答えてしまいましたが、dxlibをずっと使っていたため今回もGameProg_2012に入れれば実行出来るだろうと思い
入れていました。

ですが、かずまさんのご解答(C:\Users\user\Documents\Visual Studio 2013\Projects\script\)を見て、ここではないと判断し、「Project」の方に入れてしまいしました。
  これは報告をしないで、自己判断でやってしまい皆さんを混乱させてしまった原因だと感じました。


次にfpファイルについて

このプログラムは.txtを開くプログラムです

コード:

	int pos;
	char c;
	FILE *fp; //スクリプトファイル

	
このコードを見て.txtファイルの名前はfpだと思い.txtの名前をfpにしていました。

コード:

loadScript("./script.txt", &script);
今一度見直してみて.txtの名前はscriptということでは再認識しました。 間違っていたらご指摘お願いします





最後にprojectについて

初期はscriptというファイルでソースを書いていました。
ですが、プログラムのビルドエラーが出でしまい エラー部分を直してもwindowsデバッカーの変更がされています
というvisual studio からのメッセージが出なかったため(正確に申しますとエラーが直せていなかったため)
1回projectを変えてやり直していました。
その報告もしていませんでした。 

fpファイル、project、script.txtについて再度説明させていただきました。

変更等をする際にはきちんとご報告のほうをさせていただきます
申し訳ございませんでした。

かずま

Re: scriptファイルの開き方

#17

投稿記事 by かずま » 9年前

THムラオサ さんが書きました:http://www.usamimi.info/~guiprog/game/
URL内の第9章 ノベルゲーム用スクリプト言語の作成 ◾スクリプトを読み込む
という内容が今回のプログラムとなります。
その本の PDF版の 118-119ページのプログラムを見ました。
そのプログラムのインデントはまともでした。
なぜ、それを無茶苦茶なインデントにしてここに載せたのですか?
THムラオサ さんが書きました:

コード:

loadScript("./script.txt", &script);
今一度見直してみて.txtの名前はscriptということでは再認識しました。 間違っていたらご指摘お願いします
.txtの名前はscript ???

スクリプトファイルの名前が script.txt であると認識してください。

で、No.15の「main を次のように変えたらどうなりますか?」
という質問には答えてもらえないのでしょうか?

また、スクリプトファイルは読めるようになったのでしょうか?

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#18

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます。
NO15 mainについて
コードの書き出しありがとうございます。
残念ながら変更してみたもののできませんでした。


下記のプログラムを実行しました。

コード:

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

#define SCRIPT_MAX_LINE 1000            //スクリプトは最大1000 行まで
#define SCRIPT_MAX_STRING_LENGTH 300    //スクリプト最大文字数

typedef struct ScriptInformation_tag {
	int maxLineNumber;                  //スクリプト行数
	int currentLine;                    //現在何行目を実行しているか
	const char *filename;               //ファイル名
	char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
} ScriptInformation;

//スクリプトファイルを読み込む; 戻り値 -1:失敗, 0:成功
int loadScript(const char *filename, ScriptInformation * scriptInfo)
{
	int pos;
	char c;
	FILE *fp; //スクリプトファイル

	memset(scriptInfo, 0, sizeof(ScriptInformation)); //スクリプト情報を初期化
	fp = fopen(filename, "r");          //スクリプトファイルを開く
	if (fp == NULL) {
		printf("スクリプト%s を読み込めませんでした\n", filename);
		return -1;
	}
	pos = 0;                            // script 書き込み時に使用
	for (;;) {
		c = fgetc(fp);                  //一文字読み込み
		if (c == EOF) {                 //ファイルの終わりかどうか
			break;
		}
		if (pos >= SCRIPT_MAX_STRING_LENGTH - 1) {
			printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
			return -1;
		}
		if (c == '\n') {                //改行文字が出てきた場合
			scriptInfo->script[scriptInfo->currentLine][pos] = '\0';
			scriptInfo->currentLine++;  //次の行に移動
			pos = 0;                    //書き込み位置を0 にする
		}
		else {
			scriptInfo->script[scriptInfo->currentLine][pos] = c;
			pos++;                      //文字書き込み位置をずらす
		}
	}
	scriptInfo->maxLineNumber = scriptInfo->currentLine; //最大行数
	scriptInfo->currentLine = 0;        //読み込み中の行を 0 にする
	scriptInfo->filename = filename;    //スクリプトファイル名を設定
	return 0;
}


int main(void)
{
	int i;
	ScriptInformation script;

	if (loadScript("c:/users/user/documents/visual studio 2013/projects/project12/fp", &script) != 0) {
		return 1;
	}
	for (i = 0; i < 10; i++) {          //10 行目までを表示
		printf("%d : %s\n", i + 1, script.script[i]);
	}
	return 0;
}

かずま

Re: scriptファイルの開き方

#19

投稿記事 by かずま » 9年前

THムラオサ さんが書きました: NO15 mainについて
コードの書き出しありがとうございます。
残念ながら変更してみたもののできませんでした。
どうなりましたか? と質問しています。

Visual Studio でビルドおよび実行を行っていますよね。

main の最期の return 0; の行にブレークポイントを置いて実行してください。

ブレークポイントはご存知ですか?
行の左側のグレーの部分をクリックすると、赤丸が付きます。
この状態でデバッグ実行を開始すると、そこで実行が一時停止しますから、
コンソール画面が消えずに残ります。
そのコンソール画面にはなんと表示されましたか?
コンソール画面は、Visual Studio の画面に隠れているかもしません。
その場合は、タスクバーでコンソール画面のアプリのアイコンをクリックしてください。

また、スクリプトファイルの名前は script.txt のはずですから、
"fp" を "script.txt" に変更して試してみましたか?

c:/users/user/documents/visual studio 2013/projects/project12/ に
script.txt をちゃんと置いていますか?

script.txt の内容は何ですか?

YuO
記事: 947
登録日時: 14年前
住所: 東京都世田谷区

Re: scriptファイルの開き方

#20

投稿記事 by YuO » 9年前

かずまさんの記述に加えて,61行目のreturn 1;にもブレークポイントをおいてください。
loadScriptが0を返さなかった場合,こちらでも止める必要があります。

can110
記事: 27
登録日時: 10年前

Re: scriptファイルの開き方

#21

投稿記事 by can110 » 9年前

スクリプトファイルの正確なフルパスを確認することをお勧めします。

コマンドプロンプトにて以下を実行すると、サブフォルダも含めた当該フォルダ下の全ファイルのフルパスがfiles.txtに記録されます。
dir c:\users\user\documents /S /B > c:\users\user\documents\files.txt
この中からあなたの言われる「スクリプトファイル」のパスを特定してみてください。
オフトピック
エクスプローラの表示オプションで拡張子を非表示にしていて「script.txt.txt」になっているという落ちだったりして。

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#22

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます 
数多くの返信ありがとうございます 
では、順番に答えていきたいと思います。


NO19 かずまさんのご解答について

実行画面にはこのように表示されていました。

スクリプトc:/users/user/documents/visual studio 2013/projects/project12/fpは
読み込めませんでした。

ブレイクポイントについては存じています。

コード:

if (loadScript("c:/users/user/documents/visual studio 2013/projects/project12/fp", &script) != 0) {
		return 1;
	}
	for (i = 0; i < 10; i++) {          //10 行目までを表示
		printf("%d : %s\n", i + 1, script.script[i]);
	}
	return 0;
}
このコードのreturn 0 return 1 のところにブレイクポイントを設置しました。



スクリプトファイル
"fp" を "script.txt" に変更して試したことについて

実行画面
スクリプトc:/users/user/documents/visual studio 2013/projects/project12/fpは読み込めませんでした。

script.txtの内容について
1 @@message こんにちは,文章表示のテストです
2
3 @@message あいうえおかきくけこさしすせそ





NO20   YuOさんのご解答について
  61行目のreturn 1にもブレイクポイントを置きました。


NO21 can110さんのご解答について
コマンドプロンプトでdir c:\users\user\documents /S /B > c:\users\user\documents\files.txt
と実行したのですが、「無効なスイッチです "users"」と出ました。

1点お聞きしたいのですが、dirの後ろをスペースで1回分空けました。 
そのほかは詰めて書きました。無効となってしまうのは書き方のせいでしょうか?


今のコードやファイルの場所についてまとめます。

コード:

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

#define SCRIPT_MAX_LINE 1000            //スクリプトは最大1000 行まで
#define SCRIPT_MAX_STRING_LENGTH 300    //スクリプト最大文字数

typedef struct ScriptInformation_tag {
	int maxLineNumber;                  //スクリプト行数
	int currentLine;                    //現在何行目を実行しているか
	const char *filename;               //ファイル名
	char script[SCRIPT_MAX_LINE][SCRIPT_MAX_STRING_LENGTH];
} ScriptInformation;

//スクリプトファイルを読み込む; 戻り値 -1:失敗, 0:成功
int loadScript(const char *filename, ScriptInformation * scriptInfo)
{
	int pos;
	char c;
	FILE *fp; //スクリプトファイル

	memset(scriptInfo, 0, sizeof(ScriptInformation)); //スクリプト情報を初期化
	fp = fopen(filename, "r");          //スクリプトファイルを開く
	if (fp == NULL) {
		printf("スクリプト%s を読み込めませんでした\n", filename);
		return -1;
	}
	pos = 0;                            // script 書き込み時に使用
	for (;;) {
		c = fgetc(fp);                  //一文字読み込み
		if (c == EOF) {                 //ファイルの終わりかどうか
			break;
		}
		if (pos >= SCRIPT_MAX_STRING_LENGTH - 1) {
			printf("error: 文字数が多すぎます(% d 行目)", scriptInfo->currentLine);
			return -1;
		}
		if (c == '\n') {                //改行文字が出てきた場合
			scriptInfo->script[scriptInfo->currentLine][pos] = '\0';
			scriptInfo->currentLine++;  //次の行に移動
			pos = 0;                    //書き込み位置を0 にする
		}
		else {
			scriptInfo->script[scriptInfo->currentLine][pos] = c;
			pos++;                      //文字書き込み位置をずらす
		}
	}
	scriptInfo->maxLineNumber = scriptInfo->currentLine; //最大行数
	scriptInfo->currentLine = 0;        //読み込み中の行を 0 にする
	scriptInfo->filename = filename;    //スクリプトファイル名を設定
	return 0;
}


int main(void)
{
	int i;
	ScriptInformation script;

	if (loadScript("c:/users/user/documents/visual studio 2013/projects/project12/fp", &script) != 0) {
		return 1;   //ブレイクポイント設置
	}
	for (i = 0; i < 10; i++) {          //10 行目までを表示
		printf("%d : %s\n", i + 1, script.script[i]);
	}
	return 0;     //ブレイクポイント設置
}

script.txtファイルの場所について
 コンピュータ→ローカルディスク(c)→users→user→マイドキュメント
→visual studio 2013 →projects→project12→scriptファイル

Project12について
.cppファイルの名前はfp.cpp
.hファイルはありません

ここでまた1つ質問です。
project12をクリックするとdebug project12(ファイルアイコン) project12(SQL Server Compact Edition Database File)
project12(Microsoft Visual studio Solution) 
というのがでます  
ここにscriptファイルを保存しているのが合っているいるでしょうか?

それとも
debug project12(ファイルアイコン) project12(SQL Server Compact Edition Database File) project12(Microsoft Visual studio Solution) 
のProject12(ファイルアイコン)をクリックし、その中にいれるのでしょうか?

実行した際は
debug project12(ファイルアイコン) project12(SQL Server Compact Edition Database File)
project12(Microsoft Visual studio Solution) script.txt
の中に入れていました

かずま

Re: scriptファイルの開き方

#23

投稿記事 by かずま » 9年前

THムラオサ さんが書きました:実行画面にはこのように表示されていました。

スクリプトc:/users/user/documents/visual studio 2013/projects/project12/fpは
読み込めませんでした。
これは、"c:/users/user/documents/visual studio 2013/projects/project12/" には
"fp" という名前のスクリプトファイルがなかったということです。代わりに
"script.txt" という名前のスクリプトファイルがあるんですよね。
THムラオサ さんが書きました:スクリプトファイル "fp" を "script.txt" に変更して試したことについて

実行画面
スクリプトc:/users/user/documents/visual studio 2013/projects/project12/fpは読み込めませんでした。
main() の loadScript の "fp" を "script.txt" に変更したのなら、
スクリプトc:/users/user/documents/visual studio 2013/projects/project12/scropt.txt は読み込めませんでした。
という実行画面になるはずです。

本当に、"fp" を "script.txt" に変更しましたか?
THムラオサ さんが書きました:コマンドプロンプトでdir c:\users\user\documents /S /B > c:\users\user\documents\files.txt
と実行したのですが、「無効なスイッチです "users"」と出ました。

1点お聞きしたいのですが、dirの後ろをスペースで1回分空けました。 
そのほかは詰めて書きました。無効となってしまうのは書き方のせいでしょうか?
「無効なスイッチです "users"」と出たということは、
c:\users ではなく、c:/users と入力したということです。
/S や /B の前後のスペースはなくてもかまいませんが、
どうして、書かれている通りに実行しないんですか?
THムラオサ さんが書きました:今のコードやファイルの場所についてまとめます。

コード:

	if (loadScript("c:/users/user/documents/visual studio 2013/projects/project12/fp", &script) != 0) {
まだ、"fp" になっていますが、本当にこれが最新のソースですか?
THムラオサ さんが書きました:Project12について
.cppファイルの名前はfp.cpp
.hファイルはありません
fp.cpp とは何ですか?
main関数の定義があるソースファイルですか?
fp がソースプログラム中の変数名と分かったのに、
なぜ fp がこんなところに使われているのですか?
THムラオサ さんが書きました:ここでまた1つ質問です。
project12をクリックするとdebug project12(ファイルアイコン) project12(SQL Server Compact Edition Database File)
project12(Microsoft Visual studio Solution) 
というのがでます
ファイル名の拡張子が表示されていませんね。
拡張子を表示して次のように出てほしいのです。

Project12.sdf SQL Server Compact Edition Database File
Project12.sln Microsoft Visual Studion Solution

そうすると、script.txt だと思っていたものが script.txt.txt であったことが
分かり、script.txt ではオープンできないことになります。

あなたの使っている Windows が、7 か 8 か 10 知りませんが、
「ファイル名の拡張子を表示する」で検索して、それを実行し、
拡張子を表示してください。

それから、スクリプトファイルの置き場所は、どこでもいいんです。

ローカルディスク C: の下に、"tmp" という名前のフォルダを新規作成し、
そこに "script.txt" という名前のスクリプトファイルを置いて、
ソースを次のようにしてみたらどうですか?

コード:

if (loadScript("c:/tmp/script.txt", &script) != 0) {

can110
記事: 27
登録日時: 10年前

Re: scriptファイルの開き方

#24

投稿記事 by can110 » 9年前

THムラオサ さんが書きました: コマンドプロンプトでdir c:\users\user\documents /S /B > c:\users\user\documents\files.txt
と実行したのですが、「無効なスイッチです "users"」と出ました。

1点お聞きしたいのですが、dirの後ろをスペースで1回分空けました。 
そのほかは詰めて書きました。無効となってしまうのは書き方のせいでしょうか?
おそらくそうだと思いますが、なぜ例示したとおりに入力しないのでしょうか?
また、意図した結果にならなかった場合、まずは自分が理解でき、確実に成功する簡単な手順から試してみるようにしましょう。
今回のトピック全体にいえることですが。

たとえばdir なら単純にdir を実行→次にdir c:\users\user\documents を実行する→…
dirの使い方については以下などが参考になります。
ファイルの一覧表示(DIR)

かずま

Re: scriptファイルの開き方

#25

投稿記事 by かずま » 9年前

かずま さんが書きました:あなたの使っている Windows が、7 か 8 か 10 知りませんが、
「ファイル名の拡張子を表示する」で検索して、それを実行し、
拡張子を表示してください。

それから、スクリプトファイルの置き場所は、どこでもいいんです。

ローカルディスク C: の下に、"tmp" という名前のフォルダを新規作成し、
そこに "script.txt" という名前のスクリプトファイルを置いて、
ソースを次のようにしてみたらどうですか?

コード:

if (loadScript("c:/tmp/script.txt", &script) != 0) {
これでうまくいったとします。

ソースプログラムの中に "c:/tmp/script.txt" のような絶対パスを書きたくない、
"./script.txt" や "script.txt" のように相対パスにしたい、と思ったら、
それは、プログラムが作業ディレクトリ(カレントディレクトリ) の script.txt
というスクリプトファイルを読みますよ、という仕様だから、作業ディレクトリ
を script.txt のあるディレクトリに変更してから、プログラムを実行すれば
良いわけです。

Visual Studio で実行するなら、プロジェクトのプロパティを開いて、
[構成プロパティ] の [デバッグ] の [作業ディレクトリ] を "c:\tmp" に変更
してください。

変更する前は、$(ProjectDir) となっていて、それは、プロジェクトファイル
(今の場合、Project12.vcxproj のはず) の存在するディレクトリです。
作業ディレクトリを変更しない場合は、そこに script.txt を置けばよいのです。

とにかく、以上のことを全部試してみてください。どうなりますか?

特に、エクスプローラで拡張子を表示する設定は、プログラム開発者としては
是非やっておくべきことだと思います。

THムラオサ
記事: 17
登録日時: 9年前

Re: scriptファイルの開き方

#26

投稿記事 by THムラオサ » 9年前

ご解答ありがとうございます。
ネット工事をやっていたため、返事が遅くなってしまいました。
ですが、無事実行することができました。
本当にご迷惑をおかけしました。
ご回答していただいたすべての方々に改めてご挨拶させていただきます。
ありがとうございました。

スクリプトファイルを開けないという方は是非これを参考してください。
皆さんのおかげでこのトピックは解決となります。

can110
記事: 27
登録日時: 10年前

Re: scriptファイルの開き方

#27

投稿記事 by can110 » 9年前

解決して何よりです。
原因は何だったのでしょうか?(ファイルの配置場所の間違い?拡張子の非表示がらみ?…など)

閉鎖

“C言語何でも質問掲示板” へ戻る