C言語関係掲示板

過去ログ

No.589.文字列にa〜zA〜Zの人文字を「-X」の形で付けたい

[戻る] [ホームページ]
No.5567

似通った文字列からMAXを取り出し加工する
投稿者---にしのごう(2003/03/12 23:16:01)


文字の並びが似通った文字列から、MAXの文字列を引っ張り出し、
引っ張りだした文字列にa〜zA〜Zの人文字を「-X」の形で付け
たいのですが、良い案が浮かびません。

Taro.Yamada.
Hanako.Yamamoto.
Hanako-a.Yamamoto.
Hanako-b.Yamamoto.
Jon-P.Sato.
Lu-Will.Lu.
とあった場合、

Taro.Yamada.は、この状態がMAXとなるので、Taro-a.Yamada.と
Hanako.Yamamoto.は、「-b」が付いている状態がMAXとなるので、
Hanako-c.Yamamoto.と
Jon-P.Sato.は、この状態がMAXとなるので、Jon-P-a.Sato.と
Lu-Will.Lu.は、この状態がMAXとなるので、Lu-Will-a.Lu.と
を求めたいのですがどうすればよいですか。
MAXの状態を導きだす方法等とか、なんか上手く行かなくて困ってます。

main()
{
    char str_nm[41];
    char wk[21] ;
    char str_chr ;
    int i ;

    MAX状態を求める処理

    /* データを取り出したけど、「-x」がついていなかった */
    for(i=0 ; i<strlen(str_nm) ; i++) {
        if(str_nm[i] == '.') {
            strncpy(wk,&str_nm[i],strlen(str_nm)-i) ;
            strncpy(&str_nm[i],"-a",2) ;
            strncpy(&str_nm[i+2],wk,strlen(wk)) ;
        }
    }

    /* データ取り出したら「-x」がついていた */
    for(i=0 ; i<strlen(str_nm) ; i++) {
        if(str_nm[i] == '-') {
            if(str_nm[i+2] == '.') {
                str_chr = str_nm[i+1] ;
                break ;
            }
        }
    }
    if ((str_chr >= 'a' && str_chr <='Z') || (str_chr >= 'A' && str_chr <= 'Z')) {
        str_nm[i+1] = str_chr + 0x01 ;
    }
}




No.5581

Re:似通った文字列からMAXを取り出し加工する
投稿者---ともじ(2003/03/13 21:26:42)


こんばんは。

>文字の並びが似通った文字列から、MAXの文字列を引っ張り出し、
>引っ張りだした文字列にa〜zA〜Zの人文字を「-X」の形で付け
>たいのですが、良い案が浮かびません。

質問です。Jon-P.Sato.の場合、a〜zA〜Zで人文字を付加すると、
Jon-Q.Sato.になってしまいます。Jon-P-a.Sato.にするための
判別条件は何でしょうか。


No.5587

Re:似通った文字列からMAXを取り出し加工する
投稿者---ともじ(2003/03/15 14:00:35)


>質問です。Jon-P.Sato.の場合、a〜zA〜Zで人文字を付加すると、
>Jon-Q.Sato.になってしまいます。Jon-P-a.Sato.にするための
>判別条件は何でしょうか。

上記にご返信がないので、Jon-Q.Sato.になりますが、次のような
プログラムを作ってみました。
条件漏れなどあるかもしれませんが、upします。
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define N 6
int alpncmp(const char str1[], const char str2[], int len);

int main(void)
{
    char str_nm[N][41] = {"Taro.Yamada.", "Hanako.Yamamoto.",
                          "Hanako-a.Yamamoto.", "Hanako-b.Yamamoto.",
                          "Jon-P.Sato.", "Lu-Will.Lu."};
    char *p1, *p2, *maxp, maxstr[N][41];
    int i, j, k = 0, m, len1, len2;

    for (i = 0; i < N; i++) {
        m = i;                        /* i番目を仮にMAXとする */
        p1 = str_nm[i];
        len1 = strcspn(p1, ".");      /* .までの長さを取得 */
        if (*(p1+len1-2) == '-' && isalpha(*(p1+len1-1)) != 0)
            len1 -= 2;                /* -X の長さは含めない */
        
        /*** 既にMAXを見つけたか調べる ***/
        for (j = 0; j < k; j++) {
            if (strncmp(maxstr[j], p1, len1) == 0)    break;
        }
        if (j != k) continue;    /* 既にあれば次へ */

        /*** MAXを見つける ***/
        maxp = maxstr[k];
        *maxp = '\0';
        strncat(maxp, p1, len1);    /* -X を含めない文字列をmaxstrに設定 */
        for (j = i; j < N; j++) {
            p2 = str_nm[j];
            len2 = strcspn(p2, ".");                  /* .までの長さを取得 */
            if (strncmp(maxp, p2, len1) == 0) {       /* -X までが一致したら */
                if (alpncmp(maxp, p2, len2) < 0) {    /* maxstrより大きいときは */
                    m = j;                            /* MAXを書き換える */
                    *maxp = '\0';
                    strncat(maxp, p2, len2);
                }
            }
        }
        /*** MAXの更新 ***/
        len1 = strlen(maxp);
        if (*(maxp+len1-2) == '-') {
            if (*(maxp+len1-1) == 'z')
                *(maxp+len1-1) = 'A';
            else if (*(maxp+len1-1) == 'Z')
                printf("表現できる最大値を超えました。\n");
            else if (isalpha(*(maxp+len1-1)) != 0)
                *(maxp+len1-1) += 1;
            else
                 strcat(maxp, "-a");
        }
        else
            strcat(maxp, "-a");

        strcat(maxp, &str_nm[m][len1]);
        printf("%s\n", maxp);
        k++;
    }
    return 0;
}

/* a〜zA〜Zの大小比較 */
int alpncmp(const char str1[], const char str2[], int len)
{
    int i, c1, c2;
    
    for (i = 0; i < len; i++) {
        if (str1[i] != str2[i]) {
            /* 大文字と小文字のコードを逆転させる */
            if (islower(str1[i]) != 0)
                c1 = str1[i] - 'a' + 'A';
            else if(isupper(str1[i]) != 0)
                c1 = str1[i] - 'A' + 'a';
            if (islower(str2[i]) != 0)
                c2 = str2[i] - 'a' + 'A';
            else if(isupper(str2[i]) != 0)
                c2 = str2[i] - 'A' + 'a';
            return (c1 - c2);
        }
        if (str1[i] == '\0' && str2[i] == '\0') break;
    }
    return 0;
}


No.5592

Re:似通った文字列からMAXを取り出し加工する
投稿者---にしのごう(2003/03/17 12:13:39)


ご迷惑をおかけします。
返信が遅れて申し訳ありません。


>>質問です。Jon-P.Sato.の場合、a〜zA〜Zで人文字を付加すると、
>>Jon-Q.Sato.になってしまいます。Jon-P-a.Sato.にするための
>>判別条件は何でしょうか。
>
についてですが、判別条件はないです。
どう考えても「Jon-P-a.Sato.」にするのは、無理ではないかと
思ってきました。


No.5597

Re:動かしてみました。
投稿者---にしのごう(2003/03/19 09:55:36)


ともじさんありがとうございます。
動かしてみました。

Taro.Yamada.
Hanako.Yamamoto.
Hanako-a.Yamamoto.
Hanako-b.Yamamoto.
Jon-P.Sato.
Lu-Will.Lu.
の結果は、

Taro-a.Yamada.
Hanako-a.Yamamoto.
Jon-a-P.Sato.
Lu-Will-a.Lu.
となりました。

Hanako.Yamamoto.は、Hanako-c.Yamamoto.という結果には
ならず、「Hanako-a.Yamamoto.」となりました。
Jon-P.Satoは、Jon-P-a.Sato.もしくは、Jon-Q.Sato.という
結果にはならず、「Jon-a-P.Sato.」となりました。


No.5599

Re:動かしてみました。
投稿者---ともじ(2003/03/19 11:51:47)


>Hanako.Yamamoto.は、Hanako-c.Yamamoto.という結果には
>ならず、「Hanako-a.Yamamoto.」となりました。
>Jon-P.Satoは、Jon-P-a.Sato.もしくは、Jon-Q.Sato.という
>結果にはならず、「Jon-a-P.Sato.」となりました。

すみません。alpncmpでアルファベット以外のときに不定値で
計算していました。LSICで確認をして、たまたま上手く行っていて
気が付きませんでした。alpncmpを以下のように直してください。
int alpncmp(const char str1[], const char str2[], int len)
{
    int i, c1, c2;
    
    for (i = 0; i < len; i++) {
        if (str1[i] != str2[i]) {
            /* 大文字と小文字のコードを逆転させる */
            if (islower(str1[i]) != 0)
                c1 = str1[i] - 'a' + 'A';
            else if(isupper(str1[i]) != 0)
                c1 = str1[i] - 'A' + 'a';
            else 
                c1 = str1[i];
            if (islower(str2[i]) != 0)
                c2 = str2[i] - 'a' + 'A';
            else if(isupper(str2[i]) != 0)
                c2 = str2[i] - 'A' + 'a';
            else 
                c2 = str2[i];
            return (c1 - c2);
        }
        if (str1[i] == '\0' && str2[i] == '\0') break;
    }
    return 0;
}




No.5600

ありがとうございます。
投稿者---にしのごう(2003/03/19 12:54:17)


ありがとうございます。



No.5603

質問です。
投稿者---にしのごう(2003/03/19 15:18:12)


レスして頂いたソース中に、変数maxstrが宣言されていますが、
ソースを見てみたのですが、この変数にmaxstrをコピーや代入
している個所がないように見えました。
どこで、行っているのでしょうか。


No.5605

Re:質問です。
投稿者---ともじ(2003/03/19 15:56:15)


>レスして頂いたソース中に、変数maxstrが宣言されていますが、
>ソースを見てみたのですが、この変数にmaxstrをコピーや代入
>している個所がないように見えました。
>どこで、行っているのでしょうか。

*maxp = '\0';
strncat(maxp, p1, len1); /* -X を含めない文字列をmaxstrに設定 */

*maxp = '\0';
strncat(maxp, p2, len2);

の部分です。strncpy関数は仕様で、文字列2の長さが文字数よりも
少ない場合には、'\0'をコピーしません。
けれども、strncatは文字数にかかわらず'\0'を連結するので、
strncatを使いました。

No.5606

再度質問です。
投稿者---にしのごう(2003/03/19 19:14:14)


文字の並びが似通った文字列から、MAXの文字列を引っ張り出し、
引っ張りだす場合、「-」と「.」との間の一文字が大文字、小文字
混在の場合、上手くいきません。

Hanako.Yamamoto.
Hanako-A.Yamamoto.
Hanako-b.Yamamoto.
というならびの場合だと、

「Hanako-B.Yamamoto.」となってしまいます。
「Hanako-c.Yamamoto.」とするにはどうしたらよいですか。

お願いします。


No.5607

Re:再度質問です。
投稿者---ともじ(2003/03/19 20:15:25)


>Hanako.Yamamoto.
>Hanako-A.Yamamoto.
>Hanako-b.Yamamoto.
>というならびの場合だと、
>
>「Hanako-B.Yamamoto.」となってしまいます。
>「Hanako-c.Yamamoto.」とするにはどうしたらよいですか。

これは最初ににしのごうさんが、「a〜zA〜Zの人文字を「-X」の形で付け
たい」と言うので、わざわざそうなるようにしたのですが…。
プログラムを解析すると、どこを直せばいいのかわかると思いますよ。
「わざわざ」やってる処理をやめればいいだけです。

No.5608

ご迷惑をおかけしてます。
投稿者---にしのごう(2003/03/19 23:57:56)


ともじさん、丁寧に教えてくださってありがとうございます。

調べてみます。