C言語関係掲示板

過去ログ

No656 strtokとstrstrを使ったプログラム

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

strtokとstrstrを使ったプログラム
投稿者---さとう(2003/06/09 09:07:02)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*プロトタイプ宣言*/
    void first(char *a, char *b);

main()
{

/*変数宣言*/
    FILE *fin;
    char filename[40];
    char ss[256];
    char *p;
    int j=1;

/*ファイル名取得*/
    printf("filename = ");
    gets(filename);

/*ファイルオープン処理*/
    if( (fin=fopen(filename,"r")) == NULL )
    {
        printf("ファイルオープン無理\n");
        exit(1);
    }

/*一覧表示*/    
    while(fgets(ss,256,fin) != NULL)
    {
        printf("%s\n\n",ss);
    }

/*文字列をカンマをとって分離させる*/
    p=strtok( ss,",");

/*1項目目*/
/*同じものを見つけ出す*/
    first(ss,p);
    
/*2項目目以降*/
    while((p=strtok(NULL,",")) != NULL )
    {
        puts(p);
        if(strstr(ss,p) != NULL)
        {
            printf("同じものは「%s」です。\n",p);
        }
    j++;
    }
    
    
/*全項目数を表示*******************************/
    printf("\n全部で%d項目ありました。\n",j);
/**********************************************/

/*ファイルクローズ*/
    fclose(fin);
/******************/
    return 0;
}

/*1回目の関数*/
    void first(char *a, char *b)
    {
        if(strstr(a,b) != NULL)
        {
        printf("同じものは「%s」です。\n",b);
        }
        
        return ;
    }



<やりたいこと>
1.CSV形式で受け取ったファイル(1行20項目)を開きます。
2.項目を全て出力します。
3.項目の中で同じものがあったら出力させます。
4.全部の項目数を出力します。

strtokで2回目以降のポインタの合わせ方と
strstrの使い方がまずいようです。
先週もアドバイスいただいたのですがやっぱり
わかりませんでした。

どなたかどうすればできるのかお教えいただけないでしょうか。
よろしくお願いします。

No.7212

Re:strtokとstrstrを使ったプログラム
投稿者---ちぇっこり(2003/06/09 11:31:22)


なんか動きが、おかしいですね。
私も初心者級なんで、イロイロ試してみます。

でも、この流れだと・・・うまく動作しても・・
取り出し文字列は、読み込みCSVから自分自身を発見して、
重複になるのでは!?

No.7215

Re:strtokとstrstrを使ったプログラム
投稿者---さとう(2003/06/09 12:04:20)


アドバイスありがとうございます。
やはりそうなってしまうのですか・・・

いろいろ試して見るとメモリのエラーになってしまったりで
とても困っています。

strtokの理解が浅いのにこんなプログラムを投稿してしまい
申し訳なくおもいます。自分でも更にがんばってみますが、
もしわかりましたらアドバイスよろしくお願い致します。


No.7216

Re:strtokとstrstrを使ったプログラム
投稿者---さとう(2003/06/09 12:21:56)


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_MOJISUU 256
#define MAX_KOUMOKUSUU 100

main()
{

/*変数宣言*/
    FILE *fin;
    char filename[40];
    char ss[256];
    char bb[MAX_KOUMOKUSUU];
    char *p;
    int j=1;
    int i=0;
    int k=1;
    int cntSearch;

    
/*ファイル名取得*/
    printf("filename = ");
    gets(filename);

    
/*ファイルオープン処理*/
    if( (fin=fopen(filename,"r")) == NULL ){
        printf("ファイルオープン無理\n");
        exit(1);
    }

/*一覧表示*/    
    while(fgets(ss,MAX_MOJISUU,fin) != NULL){
        printf("%s\n\n",ss);
    }

/*文字列をカンマをとって分離させる*/
    p=strtok( ss,",");

/*ポインタで得た文字列を配列に格納する*/
/*1項目目*/
    bb[i] = *p;
    i++;
/*2項目目以降*/
    while((p=strtok(NULL,",")) != NULL )
    {
        bb[i] = *p;
        j++;
        i++;
    }
/******格納終了******/
    
/*試しに3番目を表示***************/
    printf("3番目のbb=%s",bb[2]);
/**********************************/
    
    
/*重複項目チェック*/
    for(cntSearch=0; cntSearch < i ;cntSearch++ )
    {
        while(k <= i)
        {
            if(bb[cntSearch] == bb[k])
            {
                printf("重複項目:%s\n重複箇所:%d、%d",bb[cntSearch],cntSearch,k);
            }
            k++;
        }
    }
/*重複項目チェック終了*/

/*全項目数を表示*******************************/
    printf("\n全部で%d項目ありました。\n",j);
/**********************************************/

/*ファイルクローズ*/
    fclose(fin);
/******************/
    
    return 0;
}




ポインタから配列に格納して比較する方法を考えてみました。
でもこれでもメモリのエラーが出てきます。
どなたかうまく実行できるためのアドバイスお願い致します。


No.7218

Re:strtokとstrstrを使ったプログラム
投稿者---ちぇっこり(2003/06/09 14:37:09)


こんなのどうですか?
  ※汚いプログラムですみません・・

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>

void    main()
{
    /*変数宣言*/
    FILE    *fin;
    char    filename[40];
    char    ss[256];
    char    ss_bk[256];
    char    *p;
    char    *q[20];
    int    i=0;
    int    j;
    int    k;
    int    rc;

    /*ファイル名取得*/
    printf("filename = ");
    gets(filename);

    /*ファイルオープン処理*/
    if( (fin=fopen(filename,"r")) == NULL ){
        printf("ファイルオープン無理\n");
        exit(1);
    }

    /*一覧表示*/    
    while(fgets(ss,256,fin) != NULL){
        printf("%s\n\n",ss);
    }
    /*待避*/
    strcpy(ss_bk,ss);

    /*文字列をカンマをとって分離させ、アドレスを待避*/
    p=strtok( ss,",");

    while ( p != NULL ) {
        q[i]=p;
        i++;
        /*文字列をカンマをとって分離させる(2件目以降)*/
        p=strtok( NULL,",");
    }

/*===========================================================*/
    /*表示しながら、重複も見つける*/
    p=strtok(ss_bk,",");

    while(p != NULL ){
        printf("%s",p);
        k = 0;
        /*自分自身以外の重複を見つける*/
        for(j=0; j<i; j++){
            rc = strcmp(p,q[j]);
            if(rc == 0) k++;
        }
        if(k > 1){
            printf(" ※他に重複文字列が存在します。");
        }
        printf("\n");
        p=strtok(NULL,",");
    }

    /*全項目数を表示*/
    printf("\n全部で%d項目ありました。\n",i);

    /*ファイルクローズ*/
    fclose(fin);
}


No.7220

Re:strtokとstrstrを使ったプログラム
投稿者---ちぇっこり(2003/06/09 16:07:27)


気持ち改良しました。
待避配列なくしました。
もっと綺麗にしたいけど・・私には限界!?

#include    <stdio.h>
#include    <stdlib.h>
#include    <string.h>

void    main()
{
    /*変数宣言*/
    FILE    *fin;
    char    filename[40];
    char    ss[256];
    char    *p;
    char    *q[20];
    int    i=0;        /*CSV分割ポインタ格納カウンター*/
    int    j;        /*表示カウンター*/
    int    k;        /*重複チェック用カウンター1*/
    int    l;        /*重複チェック用カウンター2*/
    int    rc;        /*文字列比較用リターンワーク*/

    /*ファイル名取得*/
    printf("filename = ");
    gets(filename);

    /*ファイルオープン処理*/
    if( (fin=fopen(filename,"r")) == NULL ){
        printf("ファイルオープン無理\n");
        exit(1);
    }

    /*一覧表示*/    
    while(fgets(ss,256,fin) != NULL){
        printf("%s\n\n",ss);
    }

    /*文字列をカンマをとって分離させ、アドレスを待避*/
    p=strtok( ss,",");

    while ( p != NULL ) {
        q[i]=p;
        i++;
        /*文字列をカンマをとって分離させる(2件目以降)*/
        p=strtok( NULL,",");
    }

/*===========================================================*/
    /*表示しながら、重複も見つける*/
    for(j=0; j<i; j++){
        printf("%s",q[j]);
        l = 0;
        /*自分自身以外の重複を見つける*/
        for(k=0; k<i; k++){
            rc = strcmp(q[j],q[k]);
            if(rc == 0) l++;
        }
        if(l > 1){
            printf(" ※他に重複文字列が存在します。");
        }
        printf("\n");
    }

    /*全項目数を表示*/
    printf("\n全部で%d項目ありました。\n",i);

    /*ファイルクローズ*/
    fclose(fin);
}


No.7221

Re:strtokとstrstrを使ったプログラム
投稿者---さとう(2003/06/09 16:11:35)


すごい!!!
私の求めたものでした。
わざわざお時間を作ってこんなにすばらしいコードを
打っていただきありがとうございました。

本当にありがとうございます。
2回目以降の使い方や待避させておくという考え方や
自分自身以外の重複を見つける考えが大変勉強になりました。

もっともっと努力してちぇっこりさんのようにプログラム
打てるようにがんばります。ありがとうございました。


No.7219

Re:strtokとstrstrを使ったプログラム
投稿者---ちぇっこり(2003/06/09 15:00:47)


>> char bb[MAX_KOUMOKUSUU];
>>  ・・・・・・・
>>ポインタから配列に格納して比較する方法を考えてみました。
>>でもこれでもメモリのエラーが出てきます。

この宣言・・
  char *bb[MAX_KOUMOKUSUU];
では!?

No.7225

Re:strtokとstrstrを使ったプログラム
投稿者---みけ(2003/06/09 17:24:34)


解決したようですが、とりあえず投稿してみます。
(ソース書いているうちに終わってしまったので)
さとうさん、ちぇっこりさんのソースとあまり違いはないですが。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAX_MOJISUU        256
#define MAX_KOUMOKUSUU    100

int main() {
    char  filename[256];        // 読み込むファイル名
    char  buf[MAX_MOJISUU];        // ファイルから一行分読み込むバッファ
    char* p[MAX_KOUMOKUSUU+1];    // 各項目を指すポインタ配列

    int i, j, k, l;                // カウンタ用変数
    int len;                    // 読み込んだ文字列の長さ
    FILE *fp;

    // ファイル名取得
    printf( "filename = " );
    gets( filename );

    // ファイルオープン
    fp = fopen( filename, "r" );
    if( fp != NULL ) {
        i = 1;
        while( fgets( buf, MAX_MOJISUU, fp ) != NULL ) {
            // 終端が改行コードの場合は削除
            len = strlen( buf );
            if( buf[len-1] == '\n' ) {
                buf[len-1] = '\0';
            }

            // 1行表示
            printf( "Line %d : %s\n", i++, buf );

            // 文字列の分解
            j = 0;
            p[j] = strtok( buf, "," );
            while( p[j] != NULL ) {
                j++;
                p[j] = strtok( NULL, "," );
            }

            // 文字列の比較
            for( k = 0; k < j; k++ ) {
                for( l = k + 1; l < j; l++ ) {
                    if( strcmp( p[k], p[l] ) == 0 ) {
                        printf( "%d 番目と %d 番目が一致[%s]\n", k + 1, l + 1, p[k] );
                    }
                }
            }

            printf( "項目数は %d 個です\n\n", j );
        }

        fclose( fp );
    }

    return 0;
}