結果が出ません。

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

結果が出ません。

#1

投稿記事 by pazumon_2525 » 9年前

./a.out printf file.c というように実行したら、


行 文字列
1:  aaaa printf("aaaaa");
30:  printf("aaaaa");
46:  printf("abcd");



のようにコマンドラインで指定した文字を検索するようなプログラムを考えました。
しかし、何も出ませんでした。
指摘お願いします。



コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define str 300

int match_str(char *a, char *b);
int main(int argc,char *argv[])
{
	FILE *fp;
	char a[str] = {'\0'};
	int cnt,num;
	
	if(argc != 2)
	{
		return 1;
	}
	fp = fopen(argv[1],"r");
	
	if(fp == NULL)
	{
		printf("ファイル %s が見つかりません\n",argv[1]);
		return 1;
	}
	while(fgets(a,str,fp)!= NULL)
	{
		cnt++;
		printf("%d\t:",cnt);
		num = match_str(a,argv[2]);
		
		if(num == 1)
		{
			printf("%s",a);
		}
	}	
	fclose(fp);
	printf("\n");
}
int match_str(char *a, char *b)
{
	int i = 0;
	int j = 0;
	int maxa,maxb;
	int flg = 0;

	while(flg == 0)
	{
		if(a[i] == '\0')
		{
			maxa = i;
			flg == 1;
		}
		i++;
	}
	i = 0;
	while(flg == 0)
	{
		if(b[i] == '\0')
		{
			maxb = 0;
			flg = 1;
		}
		i++;
	}
	for(i=0;i<maxa;i++)
	{
		if(0==strncmp(&a[i],&b[j],1))
		{
			if(maxb-1 == j)
			{
				return 1;
			}
			else
			{
				j++;
			}
		}
	}
	return 0;
}
		

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 結果が出ません。

#2

投稿記事 by みけCAT » 9年前

  • 実行コマンド名を除くコマンドライン引数を1個与えた場合
    ファイルオープンに成功し、何かデータを読みこんだ(fgetsが成功した)場合は、match_strの45~53行目の無限ループにはまります。
    この時、27行目で出力しようとした内容はバッファがフラッシュされず、出力されないかもしれません。
  • 実行コマンド名を除くコマンドライン引数が1個でない場合
    15行目で実行が終了します。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 結果が出ません。

#3

投稿記事 by みけCAT » 9年前

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define str 300

int match_str(char *a, char *b);
int main(int argc,char *argv[])
{
	FILE *fp;
	char a[str] = {'\0'};
	int cnt,num; /* cntを初期化していない */
	
	if(argc != 2) /* 条件が不自然。argc[2]を利用しているので、argc != 3の方が適するのでは? */
	{
		return 1;
	}
	fp = fopen(argv[1],"r");
	
	if(fp == NULL)
	{
		printf("ファイル %s が見つかりません\n",argv[1]);
		return 1;
	}
	while(fgets(a,str,fp)!= NULL)
	{
		cnt++;
		printf("%d\t:",cnt); /* 初期化していない自動変数の値を使っているのでundefined behavior */
		num = match_str(a,argv[2]);
		
		if(num == 1)
		{
			printf("%s",a);
		}
	}	
	fclose(fp);
	printf("\n");
	/* 新しいCでは大丈夫だが、戻り値を明示的に書いたほうがわかりやすい */
}
int match_str(char *a, char *b)
{
	int i = 0;
	int j = 0;
	int maxa,maxb;
	int flg = 0;

	while(flg == 0)
	{
		if(a[i] == '\0')
		{
			maxa = i;
			flg == 1; /* 意味のない文。flg = 1;の間違いでは?そもそも素直にfor(;;)でループしてここではbreak;でいいのでは? */
		}
		i++;
	}
	i = 0;
	/* ここに来るということはflgが0でなくなったということだが、flgを初期化していない */
	while(flg == 0)
	{
		if(b[i] == '\0')
		{
			maxb = 0; /* 詳しい仕様を追っていないが、iではなく0でいいのか? */
			flg = 1; /* 同様に素直にwhile(flg == 0)ではなくfor(;;)を使ってここではbreak;でいいのでは? */
		}
		i++;
	}
	for(i=0;i<maxa;i++)
	{
		if(0==strncmp(&a[i],&b[j],1)) /* 素直にa[i] == b[j]でいいのでは? */
		{
			/* maxbが初期化されていない場合はundefined behavior */
			/* maxb=0の場合はjがオーバーフローしなければ成り立たない(符号付き整数のオーバーフローはundefined behavior)が、
			 * j++;は高々maxa回(<=INT_MAX回)しか実行されず、jの初期値は0なので、オーバーフローは
			 * (デバッガや宇宙線などによるメモリの書き換えや、処理系の不都合による誤動作が無い)通常の実行では起こらない。
			 * よって、この式は通常の実行では常に偽である。 */
			if(maxb-1 == j)
			{
				return 1;
			}
			else
			{
				j++;
			}
		}
	}
	return 0;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

pazumon_2525
記事: 17
登録日時: 9年前

Re: 結果が出ません。

#4

投稿記事 by pazumon_2525 » 9年前

$ ./a.exe a.c printf
1 :2 :3 :4 :5 :6 :7 :8 :9 :10 :11 :12 :13 :14 :15 :16 :17 :18 :19 :20 :21 :22 :23 :24 : printf("[%d][%d]\n",y,x);
25 :26 :27 :28 :29 :30 :31 :32 :33 :34 :35 :36 :37 :38 :39 :40 :41 :42 :43 :44 :45 :46 :47 :48 :49 :50 :51 :52 :53 :54 :55 :56 :57 :58 :59 :60 :61 :62 :63 :64 ://printf("a\n");
65 :66 :67 :68 :69 :70 :71 : //printf("d\n");
72 :73 :74 :75 :76 :77 :78 :79 : //printf("b\n");
80 :81 :82 :83 :84 :85 : //printf("c\n");
86 :87 :88 :89 :90 :91 :92 :93 : //printf("c\n");
94 :95 :96 :97 :98 :99 : //printf("b\n");
100 :101 :102 :103 :104 :105 :106 :107 : //printf("d\n");
108 :109 :110 :111 :112 :113 : //printf("a\n");
114 :115 :116 :117 :118 :119 :120 :121 :

結果がこうなってしまいます。
cntも列として表示させるにはどうしたらよいですか?


pazumon_2525
記事: 17
登録日時: 9年前

Re: 結果が出ません。

#6

投稿記事 by pazumon_2525 » 9年前

$ ./a.exe printf a.c
24:            printf("[%d][%d]\n",y,x);
64:        //printf("a\n");
71:       //printf("d\n");
79:        //printf("b\n");
85:        //printf("c\n");
93:        //printf("c\n");
99:        //printf("b\n");
107:        //printf("d\n");
113:       //printf("a\n");

列の処理と結果はうまくできましたが、上のようにズレと大きな空白ができてしまいます。
どうしたら改正しますですか?
初心的な質問ですみません。

pazumon_2525
記事: 17
登録日時: 9年前

Re: 結果が出ません。

#7

投稿記事 by pazumon_2525 » 9年前

ソースです。

コード:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define str 300
 
int match_str(char *a, char *b);
int main(int argc,char *argv[])
{
    FILE *fp;
    char a[str] = {'\0'};
    int cnt = 0,num; 
    
    if(argc != 3) 
    {
        return 1;
    }
    fp = fopen(argv[2],"r");
    
    if(fp == NULL)
    {
        printf("ファイル %s が見つかりません\n",argv[1]);
        return 1;
    }
    while(fgets(a,str,fp)!= NULL)
    {
        cnt++;
        num = match_str(a,argv[1]);
        
        if(num == 1)
        {
            printf("%d:%s",cnt,a);
        }
    }   
    fclose(fp);
}
int match_str(char *a, char *b)
{
    int i = 0;
    int j = 0;
    int maxa,maxb;
    int flg = 0;
 
    while(flg == 0)
    {
        if(a[i] == '\0')
        {
            maxa = i;
            flg = 1; 
        }
        i++;
    }
    i = 0;
	flg = 0;
   
    while(flg == 0)
    {
        if(b[i] == '\0')
        {
            maxb = i; 
            flg = 1; 
        }
        i++;
    }
    for(i=0;i<maxa;i++)
    {
        if(a[i] == b[j]) 
        {
            if(maxb-1 == j)
            {
                return 1;
            }
            else
            {
                j++;
            }
        }
    }
    return 0;
}

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 結果が出ません。

#8

投稿記事 by みけCAT » 9年前

pazumon_2525 さんが書きました:列の処理と結果はうまくできましたが、上のようにズレと大きな空白ができてしまいます。
入力の通り出力されているだけではないですか?
今のコードが、このような大量の全角スペースを生成するとは考えられません。
pazumon_2525 さんが書きました:どうしたら改正しますですか?
適当な変換プログラムを書いて使うか、空白がない入力を与えたらいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 結果が出ません。

#9

投稿記事 by みけCAT » 9年前

pazumon_2525 さんが書きました:列の処理と結果はうまくできましたが、上のようにズレと大きな空白ができてしまいます。
どうしたら改正しますですか?
まず、入力例とそれに対する欲しい出力を教えてください。
例だけでなく、きちんと定義された変換規則を教えていただけるとさらにいいです。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

box
記事: 2002
登録日時: 14年前

Re: 結果が出ません。

#10

投稿記事 by box » 9年前

match_str()のかわりに、標準関数のstrstr()あたりを使う方が
簡単ではないですか?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: 結果が出ません。

#11

投稿記事 by みけCAT » 9年前

box さんが書きました:match_str()のかわりに、標準関数のstrstr()あたりを使う方が
簡単ではないですか?
このmatch_str()は第二引数が第一引数の連続とは限らない部分文字列になっているかを判定する関数であるので、
strstr()で同じ働きを再現することは難しいと思います。
例えば、

コード:

match_str("kanozyogafuraguwooraretara", "gaworare")
は1ですが、

コード:

!!strstr("kanozyogafuraguwooraretara", "gaworare")
は0となります。

むしろ、match_str()の引数の型をconst char*にし、前半を標準関数のstrlen()に置き換える方がいいでしょう。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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