文字列の操作及びFileRead_gets関数について

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

文字列の操作及びFileRead_gets関数について

#1

投稿記事 by wasawasa » 11年前

txtファイルからデータを読み込むときにtxtファイルの文に全角文字が含まれているとFileRead_getc関数では正常に読み込む事が出来ないと知ったので、txtファイルを1行ずつFileRead_gets関数でchar文字列として取り出してからデータを読み込むという構想で下記のような記述を試したところ、31行目と41行目で「error C2105: '++' には左辺値が必要です。」というエラーが発生してしまいました。
char型の文字列p[100],q[100]に対してp++としてからq[0]=p[0]とすればp++とする前のp[1]がq[0]に代入されると思っていたのですが違うのでしょうか?

また、下記の記述はFileRead_gets関数で1行目を読み込んだ後に再びFileRead_gets関数を使用することで2行目を読み込めると仮定して書いているのですが、この方法で改行を行うことは出来るのでしょうか?

以上の2点をどなたかよろしくお願いします。

コード:

#include "DxLib.h"
#include <math.h>

struct Data{
	char name[32];
};
struct Data readstr[4];

void hoge(){
	int file,i;
	int cut=0,m=0,ed=0,j=0;
	int text[32];
	char textc[32];
	char line[999];
	file=FileRead_open( "TestData.txt" ) ;
	if(file==NULL){printfDx("read error\n");return;}
	FileRead_gets(line,999,file);
	while(1){
		cut==0;
		for(i=0;i<31;i++){
			switch(_mbclen((BYTE*)line)){
				case 1:
					if(line[0]==','){cut=1;}
					else if(line[0]=='\0'){cut=2;i--;}
					else if(line[0]==EOF){ed=1;}
					else{textc[i]=line[0];}
					break;
				case 2:
					textc[i]=line[0];
					textc[i+1]=line[1];
					line++;
					i++;
					break;
			}
			if(cut==1){break;}
			else if(cut==2){
				FileRead_gets(line,999,file);
				if(line[0]==EOF){ed=1;}
				else{continue;}
			}
			line++;
		}
		strcpy(readstr[m].name,textc);
		m++;
	}
        FileRead_close(file) ;
	DrawFormatString( 0, 0, GetColor(255,255,255), "%s,%s,%s,%s",readstr[0].name,readstr[1].name,readstr[2].name,readstr[3].name);
	WaitKey(); 
}

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

		hoge();

        DxLib_End();    // DXライブラリ終了処理
        return 0;
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 文字列の操作及びFileRead_gets関数について

#2

投稿記事 by softya(ソフト屋) » 11年前

FileRead_getcでも文字コード(shift-jisなど)をちゃんと意識すれば読み込むことは可能です。

> FileRead_gets関数でchar文字列として取り出してからデータを読み込むという構想で下記のような記述を試したところ、31行目と41行目で「error C2105: '++' には左辺値が必要です。」というエラーが発生してしまいました。

lineはポインタではなく配列なので++できません。
ポインタ変数を別に用意してください。

あとコードが読みづらいので危険な感じがします。
※ 少なくともメンテナンス性には問題がありそうです。

>また、下記の記述はFileRead_gets関数で1行目を読み込んだ後に再びFileRead_gets関数を使用することで2行目を読み込めると仮定して書いているのですが、この方法で改行を行うことは出来るのでしょうか?

次の行目は読み込めます。「改行を行う」と言うのが次の行を読むという意味ならですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

wasawasa
記事: 94
登録日時: 11年前

Re: 文字列の操作及びFileRead_gets関数について

#3

投稿記事 by wasawasa » 11年前

>>softya(ソフト屋) さん
返信ありがとうございます。
ご指摘を受けてhoge関数内の記述を下記のように変えたところビルドは出来るようになりました。
ただ、実際に下記のような内容のTestData.txtを用意して実行してみると17行目から34行目の間で','まで文字列を読み込んでtextcに代入されると意図した筈が、全く違う文字列が読み込まれてしまいます。
トピックの題名から外れた質問となってしまいますが、どんな問題が起きていて正常に読み込むためにはどうすればいいでしょうか?

TestData.txt

コード:

あいuえお,かきkuけこ
さしsuせそ,たちtuてと
hoge関数記述

コード:

void hoge(){
	int file,i;
	int cut=0,m=0,ed=0,j=0;
	char textc[32];
	char line[999];
	char *linep;
	memset(line, 0, sizeof(line)); 
	//ファイルの読み込み
	file=FileRead_open( "TestData.txt" ) ;
	if(file==NULL){printfDx("read error\n");return;}
	FileRead_gets(line,999,file);
	linep=line;
	while(1){
		//テキストデータの","までの文字をtextcに読み込む
		cut=0;
		for(i=0;i<31;i++){
			switch(_mbclen((BYTE*)linep)){
				case 1:
					if(line[0]==',')
						cut=1;
					else if(line[0]=='\0')
						cut=2;
					else if(line[0]==EOF)
						ed=1;
					else
						textc[i]=line[0];
					break;
				case 2:
					textc[i]=line[0];
					textc[i+1]=line[1];
					linep++;
					i++;
					break;
			}
			//改行,「,」による読み込み停止の処理
			if(cut==1){break;}
			else if(cut==2){
				i--;
				FileRead_gets(line,999,file);linep=line;
				if(line[0]==EOF)
					ed=1;
				else
					continue;
			}
			linep++;
		}
		//変数への代入
		strcpy(readstr[m].name,textc);
		m++;
		//読み込みの暴走の防止
		if(m>=4){break;}
	}
	FileRead_close(file) ;
	DrawFormatString( 0, 0, GetColor(255,255,255), "読み込み%s,%s,%s,%s",readstr[0].name,readstr[1].name,readstr[2].name,readstr[3].name);
	WaitKey(); 
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 文字列の操作及びFileRead_gets関数について

#4

投稿記事 by softya(ソフト屋) » 11年前

デバッガでステップ実行しながら変数の変化は確認されていますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

かずま

Re: 文字列の操作及びFileRead_gets関数について

#5

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

wasawasa さんが書きました: トピックの題名から外れた質問となってしまいますが、どんな問題が起きていて正常に読み込むためにはどうすればいいでしょうか?
_mbclen は、setlocale(LC_CYPE, ""); を実行しないと、
常に 1 を返すはずです。
linep を用意したのに、それを使っていません。
line[0] と line[1] を、linep[0] と linep[1] に変えないといけないでしょう。
file は int なので、ポインタである NULL ではなく、0 と比較しましょう。
EOF は負の整数なので、char である line[0] に入っていないと考えた方がいいでしょう。

FileRead_getc を使った方が簡単なのでは?

コード:

void hoge()
{
    int file, i, j, c;

    file = FileRead_open("TestData.txt");
    if (file == 0) { printfDx("read error\n"); return; }
    for (i = 0; i < 4; i++) {
        char *p = readstr[i].name;
        for (j = 0; j < 31; j++) {
            c = FileRead_getc(file);
            if (c == ',' || c == '\n' || c == '\0' || c == -1) break;
            *p++ = c;
        }
        *p = '\0';
    }
    FileRead_close(file);

    DrawFormatString(0, 0, GetColor(255, 255, 255), "読み込み:%s,%s,%s,%s",
        readstr[0].name, readstr[1].name, readstr[2].name, readstr[3].name);

    WaitKey(); 
}

wasawasa
記事: 94
登録日時: 11年前

Re: 文字列の操作及びFileRead_gets関数について

#6

投稿記事 by wasawasa » 11年前

返信ありがとうございます。
色々と変数名の変更をし忘れていたみたいでお恥ずかしい限りです。おかげで無事実行する事が出来ました。
そしてFileRead_getc関数で2バイトの文字を正確に読み込めるとは思いませんでした。
この作業ではFileRead_getc関数を使用したいと思います。
いろいろとありがとうございました。

閉鎖

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