ほとんどコピペで所々自分の環境に合わせて手直しする程度なので、なんとかいっているのですが、
なぜか文を表示した際に最後に”.”がつくことがあります、しかもコレがデバッグのたびについたりつかなかったりします。
なんとか消したいと思い、アレコレ試したのですが自分では解決不能でした。
VC++2008 DXライブラリ使用 OSは7です。
参考にしているサイト http://karetta.jp/book-node/game-programming/235295
どうかよろしくお願いします。
一応全体のソース載せます
#include <stdio.h>
#include <string.h>
#include "DxLib.h"
#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行の最大文字数は SCRIPT_MAX_STRING_LENGTH)
//src : 分割したい文字列
//dest: 分割された文字列
//delim: 区切り文字
//splitNum : 最大分割数
void splitString(const char* src, char* dest[], const char* delim, int splitNum)
{
int i;
char* cp;
char* copySrc;
char *nexttoken;
//元の文章をコピーする
copySrc = (char*)malloc( sizeof(int) * SCRIPT_MAX_STRING_LENGTH + 1);
//↓危険↓ 第二引数 適当です
strncpy_s( copySrc,( sizeof(int) * SCRIPT_MAX_STRING_LENGTH + 1), src, SCRIPT_MAX_STRING_LENGTH );
// strncpy( copySrc, src, SCRIPT_MAX_STRING_LENGTH );
// DrawFormatString(300,400,GetColor(255,255,0),"%d",(sizeof(int)* SCRIPT_MAX_STRING_LENGTH+1));
cp = copySrc;
//strtokを使って copySrc をdelim区切りで分割する
for( i = 0; i < splitNum ; i++ ) {
//分割対象文字列が無くなるまで分割
if( (dest[i] = strtok_s(cp,delim,&nexttoken)) == NULL ) {
break;
}
//2回目にstrtokを呼び出す時は,cpをNULLにする
cp = NULL;
}
//分割された文字列の最後の要素はNULLとしておく
dest[i] = NULL;
}
int loadScript(const char* filename, ScriptInformation* scriptInfo)
{
int pos;
char c;
//スクリプトファイル
FILE* fp;
//スクリプト情報を初期化
memset( scriptInfo , 0, sizeof(ScriptInformation) );
//スクリプトファイルを開く
// fp =
fopen_s(&fp,filename, "r");
if( fp == NULL ) {
//ファイル読み込みに失敗
// printf("スクリプト %s を読み込めませんでした\n", filename);
return -1;
}
//script書き込み時に使用
pos = 0;
for( ;; ) {
//一文字読み込み
c = fgetc ( fp );
//ファイルの終わりかどうか
if( feof( fp ) ) {
break;
}
//文章先頭の空白部分を読み飛ばす
while( (c == ' ' || c == '\t') && pos == 0 && !feof( fp ) ) {
c = fgetc( fp );
}
if( pos >= SCRIPT_MAX_STRING_LENGTH - 1 ) {
//1行の文字数が多すぎる
printf("error: 文字数が多すぎます (%d行目)", scriptInfo->currentLine );
return -1;
}
//改行文字が出てきた場合,次の行へ移動
if( c == '\n' ) {
//空行は読み飛ばす
if( pos == 0 ) {
continue;
}
//\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 decodeScript(const char* scriptMessage)
{
//分割されたスクリプト文
char* message[100];
//文字列分割時の区切り文字
const char* delim = " ";
//スクリプト分割
splitString( scriptMessage, message, delim, 100 );
//分割に失敗した場合
if( message[0] == NULL ) {
return 0;
}
//scriptの仕様
//
//@@message 文字列
//--- 文字列をメッセージとして表示する
//
//@@drawgraph x y filename
//--- filenameで指定した画像ファイルを(x, y)の位置に表示
//message[0] が @@message の時は,メッセージ命令が来たと判断
if( strncmp(message[0], "@@message", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
DrawFormatString(0,200,GetColor(255,255,0),"メッセージ : %s\n", message[1] );
return 1;
}else if( strncmp(message[0], "@@drawgraph", SCRIPT_MAX_STRING_LENGTH) == 0 ) {
DrawFormatString(0,200,GetColor(255,255,0),"画像 %s 表示 -- x座標 : %d, y座標 : %d\n",
message[3], atoi( message[1] ), atoi( message[2] ) );
return 1;
}
//注意点: エラー処理を行っていない ( message[2] )が存在しなかった場合など
//例えば messageの全要素を全てNULL で埋めておき,message[2] がNULLの場合は
//エラー処理を行うなどの手が考えられる
// DrawFormatString(0,200,GetColor(255,255,0),"sitataka");
return 0;
}
void printElements(char* elem[])
{
int i;
for( i = 0; elem[i] != NULL; i++ ) {
DrawFormatString(0,i*16+200,GetColor(255,255,0),"%d : %s\n", i + 1, elem[i] );
}
}
int main()
{
int i;
ScriptInformation script;
char* dest[100];
const char* delim = " ";
loadScript( "test.txt", &script );
//10行目までを表示
for( i = 0; i < 10; i++ ) {
// DrawFormatString(0,i*16,GetColor(255,255,0),"%d : %s\n", i + 1, script.script[i] );
}
for( i = 0; decodeScript( script.script[i] ) != 0 ; i++ );
return 0;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
WaitKey();
main();
WaitKey();
return 0;
}
@@message いろはにほへと
とだけ入れてあります。