2

私は c で自分自身を訓練しています。私の目標は、ファイルを読み取り、その中に特定の文があるかどうかを確認することです。指定された文がファイルに存在するかどうかにかかわらず、関数はそれぞれ「見つかった」または「見つからなかった」を返す必要があります。/文は記号で区切られています。

Example of file:
1,2,3,4/
car, house, hotel/
2,age,12/
1,2/
1,2,3,5/
house, car/

Example of word to look for:
1,2/

私の考えは、毎回ファイルから文を取得して配列(aryと呼ばれる)に入れ、配列(ary)が、探している特定の文を含む配列(文と呼ばれる)と等しいかどうかを確認することです、その配列 (ary) をファイル内の次の文に再利用します。

私はこのコードを書きました:

#include <stdio.h>

void main()
{
    char *sentence;
    FILE *my_file;
    char *ary;
    int size = 500;
    int got;
    int ind=0;
    int rest;
    int found=0;

    sentence="1,2";


    my_file=fopen("File.txt", "r");

    if(my_file==NULL)
    {
        printf("I couldn't open the file\n");
    }
    else
    {
        ary = (char*)malloc(500*sizeof(char));
        while((got=fgetc(my_file))!=EOF)
        {
            if(got!='/')
            {
                ary[ind++]=(char)got;
            }
            else
            {
                ary[ind++]='\0';
                rest = compare(sentence,ary);
                if(rest==0)
                {
                    found =1;
                    printf("found\n");
                    return;
                }
                ind=0;
                free(ary);
                ary = (char*)calloc(500, sizeof(char));
            }
        }
        if(found==0) 
        {
            printf("not found\n");
        }
        fclose(my_file);
    }
}




int compare(char str1[], char str2[])
{
    int i = 0;
    int risp;
    if(str1>str2 || str1<str2) 
    {
        risp=-1;
    }
    if(str1==str2)
    {
        while(str1[i++]!='\0')
        {
            if(str1[i]!=str2[i]) risp=1;
        }
    }

    return risp;
}

コンパイルはできますが、正しく動作せず、その理由がわかりません。誰かが私の間違いを指摘したり、より良い解決策を教えてもらえますか?

編集:文に関連する2つのstrを印刷すると問題ありませんが、最初の印刷後のもう1つは、単語の前に区切りを付けて印刷を続けます。次のように:

Str1:1,2
Str2:1,2,3,4
Str1:1,2
Str2:
car, house, hotel
Str1:1,2
Str2:
2,age,12
Str1:1,2
Str2:
1,2
Str1:1,2
Str2:
1,2,3,5
Str1:1,2
Str2:
house, car

これは私の問題ですか?私はそれを解決しようとしました...

4

3 に答える 3

2

str1 と str2 は実際にはポインターです (文字列の最初の要素が格納されているメモリ位置を参照します)。したがって、> と == を使用して str1 と str2 を比較すると、それらのメモリ位置のみが比較されます。それらが異なる場所にある場合 (そうなる)、str1 と str2 が等しくなることはありません。

やりたいことは、str1 と str2 の両方をステップ実行して、値を比較することです。ポスターの演習としてそれを残します。

于 2013-03-08T23:12:30.330 に答える
1

C で文字列の一部を移動することは間違いなく実行可能ですが、ポインターと割り当てが舞台裏でどのように機能しているかを本当に理解する必要があるため、面倒です。では、文字列の一部を移動する必要のない別のアプローチを提案できますか?

まず、ファイル内の文字列を見つける方法の定義を疑似コードに書き留めましょう。

def file_contains_string(file, string):
   if (file is empty):
       return "not found"
   else if (initial_part_of_file_equals(file, string)):
       return "found it!!!"
   else
       return file_contains_string(drop_first_character(file), string)

つまり、「ファイルの最初の部分が文字列と等しい場合、またはファイルの後半部分が文字列と等しい場合、ファイルには文字列が含まれます。」

C への翻訳は次のとおりです。

int file_contains_string(FILE *file, char *str)
{
    if (feof(file)) return 0;
    if (initial_part_of_file_equals(file, str)) return 1;
    fgetc(file);  /* discard leading character from the file */
    return file_contains_string(file, str);
}

では、どのように実装しinitial_part_of_file_equalsますか? ファイルの最初の部分は最初の文字が等しい場合に一致し、残りの文字列はファイルの最初の部分の最初の文字以降と一致します。

def initial_part_of_file_equals(file, string):
   if is_empty(string):
      return True
   else if first_character(string) == first_character(file):
      return initial_part_of_file_equals(drop_first_character(file),
                                         drop_first_character(string))
   else return False

それをどのように翻訳しますか?C では、「文字列」は単なる文字配列へのポインターであるため、ポインターを進めるだけで文字列の「最初の文字を削除」します。そして、ポインターを逆参照するだけで、文字列の最初の文字を比較します。

int initial_part_of_file_equals(FILE * file, char * str)
{
    if !(str*)      return 1;  /* Test for empty string */
    if (feof(file)) return 0;  /* Test for empty file */

    char c = fgetc(file);      /* get first character from file */

    int result = (c == *str)
                 && initial_part_of_file_equals(file, str++);

    ungetc(c, file);

    return result;
}

そこungetcにあることが重要です - マッチの最初の部分だけであればstr、入力ストリームの対応する部分を実際に消費しないようにしたいのです。

于 2013-03-09T16:18:29.640 に答える
1

ゆっくりゆっくり私も自分で解決策を見つけました。私はそれがエレガントではないことを知っていますが、それは私にとって小さな勝利です.

char c;
char str[]="1,2/";
FILE * f;
int i=0; 

f=fopen("File.txt", "r");
if (f==NULL) perror ("Error opening file");
else
{
   while ((c=(char)fgetc(f)) != EOF) {
      if((c==str[i]))  {
          if (c=='/')
            {
              printf("FOUND\n");
              return;
            }
          i++;
      }
      else i=0;
      if(c=='/')
          i=0;
    }
    printf("NOT FOUND\n");
    fclose (f);
  }
于 2013-03-10T17:30:59.440 に答える