【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※返信付き投稿の削除は禁止!
 ※マルチポスト(多重投稿)は慎んで!

 詳しくはこちら


本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール掲示板2こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧

No.21819

文字列の置換
投稿者---ともかず(2005/07/10 03:36:13)


以下のプログラムで、文字列s1内にある文字列s2を文字列s3に置換したいのですが、このコードだと、ソースファイルをSJIS、入力ファイルもSJISだと正しく動作しますが、ともにEUCにすると正しく動作しません。
実行環境は、UNIX(Cygwin)なのですが・・・
よくわからないので、教えて下さい。


#include<stdio.h>
#include<string.h>
char *permute_str(const char *s1, const char *s2, const char *s3);

int main()
{
FILE *fp_i;
char *res;
char a[100],fname[256],fname2[256],sstr[100],cstr[100];
int len;

printf("検索されるファイル名 : ");
scanf("%s",fname);

printf("置換前の文字列 : ");
scanf("%s",sstr);

printf("置換後の文字列 : ");
scanf("%s",cstr);
printf("\n");

if( (fp_i=fopen(fname,"r"))==NULL){
printf("ファイル %s が見つかりません\n",fname);return;
}

while(fgets(a,100,fp_i)!=NULL){

// 改行コードの削除
len = strlen(a);
if( a[len-1] == '\n' ){
a[len-1] = '\0';
}

// 1ラインの文字列検索&置換
while(1){
res = permute_str(a, sstr, cstr);

// 次の行の読み込みへ
if (res == NULL){
break;
}
// 同一ラインの検索
else{
memset(a, '\0', sizeof(a));
strcat(a, res);
}
}
}
fclose(fp_i);
return;
}

/**********************************************
引数
s1 検索の対象となる文字列へのポインタ
s2 検索する文字列へのポインタ
s3 置換する文字列へのポインタ
戻り値
置換後の文字列の先頭アドレス
***********************************************/
char *permute_str(const char *s1, const char *s2, const char *s3)
{
int i=0, max_s1, max_s2;
char result[256];
char *sp;
int tmp1_len, tmp3_len;


// 置換バッファ初期化
memset(result, '\0',sizeof(result));

// 検索文字列の最大文字数(半角)を調べる
max_s2 = strlen(s2);

// 検索対象文字列の最大文字数(半角)を調べる
max_s1 = strlen(s1);

sp = strstr(s1,s2);
if (sp == NULL) {
printf("指定された文字列が存在しません\n");
return NULL;
}

tmp1_len = sp - s1;
tmp3_len = (s1 + max_s1) - (sp + max_s2);
memcpy(result, s1, tmp1_len);
strcat(result, s3);
memcpy(result + strlen(result), s1 + tmp1_len + max_s2, tmp3_len);

printf("変更後文字列=%s\n", result);
return result;
}


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:文字列の置換 21822 もぐりん 2005/07/10 11:08:13
<子記事> Re:文字列の置換 21855 ぽこ 2005/07/11 23:10:43


No.21822

Re:文字列の置換
投稿者---もぐりん(2005/07/10 11:08:13)


まず文字コードについて調べてみては?
SJISとEUCで何が異なるのかを理解できれば、おのずと答えは
出てくると思います。
googleで検索すれば、情報は得られます。


この投稿にコメントする

削除パスワード

No.21823

Re:文字列の置換
投稿者---ともかず(2005/07/10 13:04:20)


>まず文字コードについて調べてみては?
>SJISとEUCで何が異なるのかを理解できれば、おのずと答えは
>出てくると思います。
>googleで検索すれば、情報は得られます。

返信ありがとうございます。
プログラムの問題ではなく、動作環境がCygwin上なのが原因と考え始めています。
UNIXアプリを作りたいので・・・
プログラムソースは、EUCでコンパイルしています。
このプログラムからprintfで、日本語表示しています。

Cygwinのコンソールは、WindowsのSJISコンソールなので、文字が化けるだけでは?
だとすると、Cygwin上で、日本語を扱うUNIXアプリなどを動作させる場合、何か解決方法はあるのでしょうか?
このプログラムの入力となるテキストファイルなどもEUCコードです。
ソースも入力ファイルもSJISにすれば、正しく動作しますが、
それでは意味がありません。
また、プログラムからの scanf 要求などに対しても
EUCとして日本語も入力したいです。
どうすれば良いでしょうか?
よろしくお願い致します。



この投稿にコメントする

削除パスワード

No.21824

Re:文字列の置換
投稿者---かずま(2005/07/10 15:48:56)


> このプログラムの入力となるテキストファイルなどもEUCコードです。
> ソースも入力ファイルもSJISにすれば、正しく動作しますが、
> それでは意味がありません。
strstr() を使っている限り、SJIS でも正しく動作しません。
例えば、"白黒" という文字列は、94 92 8d 95 00 です。
"注" という文字列は、92 8d 00 ですから、次のプログラムで、思い通りの
結果が出ません。

    char s1[] = "白黒";
    char s2[] = "注";
    char *p = strstr(s1, s2);
    if (p) puts("found");

最初の質問のプログラムが字下げされていなくて、非常に不愉快なので、
解決方法の提示はいたしません。



この投稿にコメントする

削除パスワード

No.21825

Re:文字列の置換
投稿者---ともかず(2005/07/10 17:13:38)


見づらくて大変申し訳ありません。
なんとか解決方法を教えていただけないでしょうか?




この投稿にコメントする

削除パスワード

No.21826

Re:文字列の置換
投稿者---もぐりん(2005/07/10 21:13:08)


その前に、「Cygwinなんでも掲示板」に同じ内容の質問が
ありますが、もしかして同じ人?

http://sohda.net/cygwin/treebbs/treebbs.cgi?log=2972

違ってたら、すみません。
同じ人なら、マルチポストなので誰も答えてくれないと思いますよ。
それと、Cygwinのコンソールは環境変数LANGでEUCやSJISに変更できます。
Cygwin関連の書籍を購入して勉強してください。




この投稿にコメントする

削除パスワード

No.21855

Re:文字列の置換
投稿者---ぽこ(2005/07/11 23:10:43)


文字コードのことはよく分かっていないので、別の指摘をば。

>char *permute_str(const char *s1, const char *s2, const char *s3)
>{
> char result[256];
(略)
> return result;
>}

関数内ローカル変数のポインタを戻り値として返すのは止めたほうが
良いです。
置換した後の文字列のバッファをmalloc()で確保するか、
引数で渡しましょう。


この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    ログ    タグ一覧