文字列の\nの取り扱いについて

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ものらす

文字列の\nの取り扱いについて

#1

投稿記事 by ものらす » 15年前

わかる方がいましたら是非回答をお願いします。

ゲームの会話シーンなどで文字列を少しずつ表示させたいのですが、その際複数行を出せるようにしたいのです。少しずつ出す方法はゲームプログラミングの館のサウンドノベル風文字列表示法を使っています。

今日は
とっても
いい天気ですね。

この例ですと、一度に3行出ていることになります。

そして現在エクセルに書き込んだメッセージを配列に代入させるところまではできたのですが、
\nの扱いに困っています。

メッセージの代入は
mes[256] = "今日は\nとっても\nいい天気ですね。";
のように入っている状態です(と思う)。
これをmes_disp[256]に少しずつ代入して、少しずつ表示させます。
printfDxでmesとmes_dispを表示させると、しっかりと意図したところで改行がなされています。

しかし先ほどのmesもしくはmes_dispをDrawFormatStringで表示させてもエスケープシーケンスの\nは使用できないようなので、
今日は..とっても..いい天気ですね。というように表示されて改行がされません。

そこでmes_dispを
mes_disp[4][64]
という形に変更し、mes_disp[0]は一行目、mes_disp[1]は二行目…と最大で4行表示させようと考えました。
なので、まずはmesの中から\nの位置を知らなければ!ということで、テスト的に…
for(int i=0; i<256; i+=2;){//全角単位で読み込むためi+=2
    if(mes=='\n') printfDx("確認");
}

としてみたところ、「確認」の文字が表示されませんでした。
ここでi+=2のところをi++に変更すると、今度は「確認」の文字が表示されます。
i+=2なのでmes[1]やmes[3]のように奇数に\nが入っていた場合、飛ばされてしまい上手く「確認」の文字が表示されないのもわかりますが、
私の場合は全て全角文字しか使用していません。
つまり「今日は\nとっても\nいい天気ですね」の場合
一つ目の\nはmes[6]に、二つめの\nはmes[15]となり、少なくとも一つ目の\nは認識されるはずです。
なのにもかかわらず一度も「確認」の文字が表示されないのはどういうことなのでしょうか…?



そして申し訳ないですがもう一つ…
龍神録プログラミングの館のエクセルを使って敵の出現データを作ってみようにて
一番初めに宣言されている、int input[64]とchar inputc[64]は何故わざわざ分けられているのでしょうか?
他の部分は全て理解できたのですが、ここだけが理解できません…
int n,num,i,fp;
        char fname[32]={"../dat/csv/storyH0.csv"};
        int input[64];//コレ!!
        char inputc[64];//とコレ!!

        fp = FileRead_open(fname);//ファイル読み込み
        if(fp == NULL){
                printfDx("read error\n");
                return;
        }
        for(i=0;i<2;i++)//最初の2行読み飛ばす
                while(FileRead_getc(fp)!='\n');

        n=0 , num=0;
        while(1){
                for(i=0;i<64;i++){
                        inputc=input=FileRead_getc(fp);//1文字取得する
                        if(inputc=='/'){//スラッシュがあれば
                                while(FileRead_getc(fp)!='\n');//改行までループ
                                i=-1;//カウンタを最初に戻して
                                continue;
                        }
                        if(input==',' || input=='\n'){//カンマか改行なら
                                inputc='\0';//そこまでを文字列とし
                                break;
                        }
                        if(input==EOF){//ファイルの終わりなら
                                goto EXFILE;//終了
                        }
                }

non

Re:文字列の\nの取り扱いについて

#2

投稿記事 by non » 15年前

>for(int i=0; i<256; i+=2;){//全角単位で読み込むためi+=2

エラーがあるのが原因では?

2つめはわからないです。

yskey

Re:文字列の\nの取り扱いについて

#3

投稿記事 by yskey » 15年前

僕もサウンドノベル風文章表示を作りましたが、DXライブラリ置き場さんのサンプルプログラムにある
「サウンドノベル風文字列描画」がとても参考になりました。(DxLibを使ってればの話ですが)

int input[64]とchar inputc[64]に分ける理由は
int input[64]に直接エクセルの数値を読み込むよりも、char inputc[64]に入れてからatoi関数で数値に変換してint input[64]に入れる方が安全だからじゃないでしょうか?

dic

Re:文字列の\nの取り扱いについて

#4

投稿記事 by dic » 15年前

エクセルで文章を入力しているようでしたら
改行が\r\nになっている可能性もありますので

mes[256] = "今日は\nとっても\nいい天気ですね。";

とたしかになっているか変数の中身を確かめてください

non

Re:文字列の\nの取り扱いについて

#5

投稿記事 by non » 15年前

>int input[64]に直接エクセルの数値を読み込むよりも、char inputc[64]に入れてからatoi関数で数値に変換してint input[64]に入れる方が安全だからじゃないでしょうか?

違うとおもうけどなぁ。作者に聞かないとわからないけど、
FileRead_getc が int型を返すからint型に一回いれて、atoiで数値に変換したいから、
文字列にするために再度char型に入れたのではないでしょうか?
でも、スラッシュとスラッシュ以外でintとcharでわけているのはよくわからないです。

Libra

Re:文字列の\nの取り扱いについて

#6

投稿記事 by Libra » 15年前

No.24805で自分が質問してJustyさんが答えてくれました。
↓過去ログより


Name: Justy

 まず第一に FileRead_getc() / fgetc()の戻り値は int型です。
 その戻り値を charで受けると、EOFの判定が正しくできないことがあります。
 その為、文字列として格納するために inputcに、EOFや文字の判定の為の変数として inputに格納しているのでしょう。
 とはいえ、inputに関しては配列である必要はなく、ふつうの int型の変数でいいとは思います。


一度公開したものを修正すると、全ての章を変えないといけなくなるので、
int inputが配列なのは、そのままらしいです。

ものらす

Re:文字列の\nの取り扱いについて

#7

投稿記事 by ものらす » 15年前

皆様ありがとうございます。

DXライブラリ置き場のサンプルも参考にして
意図するとおりに動かすことが出来ました。

\nについては
mes[256] = エクセルから文章読み込み;
for(int i=0; i<256; i++){
	if(mes=='\r')
		printfDx("確認");
}


のように記述してみたところ、確かに\rが確認できました。
そんな仕様があったのですね…。
しかしそれはそれで気になることがあります。

私はエクセルを使用して文章を読み込んでいるわけですが、
同時に色々と分別の為、数値も一緒に読み込んでいます。

すると、行の最後の数値が2だったとすると、
変数に代入されたときには「2\r」と代入されていることになります。(\nは代入されないようにしています)
\rが余分についてしまうのです。
\rの仕様を知った今であれば、対策も出来ますが、
今までもエクセルを使用した読み込み方法はやってきました。
しかし、特別今まで\rによる不具合は見られませんでした。

実際に私が最初に書きました、エクセルを使って敵の出現データを作ってみよう。
のコードを見ましても、\rは特に考えずに書かれているように見えます。

\rの代入は無視できるものなのでしょうか?


あとinputc,inputの件もありがとうございます。
つまり、FileRead_getcの戻り値はint型である。
それを直接inputc[64]のchar配列に入れると、EOFの判定が出来なくなることがある。
それを回避するためにint型のinput[64]に代入して判定をさせている。という解釈で大丈夫ですか?

ちなみに
inputc=input=FileRead_getc(fp);
の表記は
input=FileRead_getc(fp);
inputc=input;
と書いているのと同じになるのかそれとも…
input=FileRead_getc(fp);
inputc=FileRead_getc(fp);
と書いているのと同じになるのかどちらでしょうか?

Libra

Re:文字列の\nの取り扱いについて

#8

投稿記事 by Libra » 15年前

> ちなみに
> inputc=input=FileRead_getc(fp);
> の表記は
> input=FileRead_getc(fp);
> inputc=input;
> と書いているのと同じになるのかそれとも…
> input=FileRead_getc(fp);
> inputc=FileRead_getc(fp);
> と書いているのと同じになるのかどちらでしょうか?

後者↓だと、FileRead_getc関数を2回呼び出していることになるので、
input = FileRead_getc(fp);
inputc = FileRead_getc(fp);

結果が違う様になってしまいます。
前者が意図した処理内容となります。

ものらす

Re:文字列の\nの取り扱いについて

#9

投稿記事 by ものらす » 15年前

Libraさん>
あ、確かに
input = FileRead_getc(fp);
inputc = FileRead_getc(fp);
だと結果が異なってしまいますね(汗)
ということはchar型(inputc)にint型(input)を代入しているということですか?

シャエ

無題

#10

投稿記事 by シャエ » 15年前

プログラミング初心者です。

敵が放った弾の現在の位置って、どういう風に考えたらいいですかね?
たとえばx軸300、y軸100にいる敵が角度shotatan2(n)(つまり自機狙い)のspd1.0で放った弾はcnt150で、どの座標にいるかの考え方です。

うまく考えることのできる方、教えてもらえないでしょうか?

kazuoni

Re:無題

#11

投稿記事 by kazuoni » 15年前

これからスレを立てるときには、タイトルをつけてください。

>敵が放った弾の現在の位置
龍神録を前提にしているのかどうなのかわかりませんが・・・
構造体bullet_tには弾の座標がメンバとしてあるので、
それを参照すればよいのでは?

シャエ

Re:無題

#12

投稿記事 by シャエ » 15年前

すみません今度から気をつけます。

ありがとうございました。

閉鎖

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