0

次のようなファイルからすべての行を読みたい:

readEveryLine
{       
  "Bart [m]" -> "Marge [f]";  
  "Lisa [f]" -> "Homer [m]"; 
  ...      
}

使いたい:

  1. ファイルを 1 行ずつ読み取る fgets()
  2. strncmp() を使用して、すべての行を指定された文字列と比較するか、適切な形式であることを確認します

私が持っているもの:

while(fgets(*file_string, MAX_INPUT_STDIN, file) != NULL)
{       
  changeLastC(*file_string);  // function to change \n into \0 

    if (strncmp(*file_string, "readEveryLine\0", 14) == 0)
    {
      if (strncmp(*file_string, "{\0", 2) == 0)
      {
        // check the first -> relation
      }
    }
    else
    {
      printf("Error Parsing\n");
    } 
}

問題は、エラー解析が表示されるだけで、ここで何が間違っていたのかわかりません。

助けてくれてどうもありがとう!

ここで、いくつかのことを行いました (最初の 2 行の解析が機能するようになりました)。どうもありがとう。

if ((fp = fopen("df.dot","r")) == NULL)
{
  printf("Error: File Open\n");
  return 1;
}


int row = 0; // check row 1

while (fgets(buffer, MAX_PARSING, fp))
{        
  if ((row == 0) && strncmp(buffer, "readEveryLine\n", 14) == 0)
  {
    printf("%s", buffer);
  }
  else
  {
    printf("Parsing Error 1\n");
  }
}


int row1 = 1; // check row 2

while (fgets(buffer, MAX_PARSING, fp))
{     
  if ((row1 == 1) && strncmp(buffer, "{\n", 2) == 0)
  {
    printf("%s", buffer);
  }
  else
  {
    printf("Parsing Error 2\n");
  }
}


int row2 = 2; // check other rows (dynamic, could be even more or less)

while (fgets(buffer, MAX_PARSING, fp))
{ 
  if ((row2 == 2) && strncmp(buffer, "  ", 2) == 0)
  {
    const char *p1 = strstr(fp, "\"")+1;
    const char *p2 = strstr(p1, " [m]\"");
    const char *p3 = strstr(p1, " [f]\"");

    // extract male persons
    if (p1 && p2)
    {
      size_t len1 = p2 - p1;
      char* res1 = (char*)malloc(sizeof(char)*(len1 + 1));
      strncpy(res1, p1, len1);

      res1[len1] = '\0';

      // give res1 for functionMale() to work on that string
    }

    // extract female persons
    else if (p1 && p3)
    {
      size_t len2 = p3 - p1;
      char* res2 = (char*)malloc(sizeof(char)*(len2 + 1));
      strncpy(res2, p1, len2);

      res2[len2] = '\0';

      // give res2 for functionFemale() to work on that string
    }

    else if (strcmp(buffer, " -> ") == 0)
    {
      // work in progress (quite complicated to do this i think)
      // it has to be a realtion between two people
    }

    else if (strcmp(buffer, ";") == 0)
    {
      // work in progress
      // this sign can either exist like this:
      // "Bart [m]" -> "Marge [f]";

      // or like this:
      // "Marge [f]";
    }

    break;
  }
  else
  {
    printf("Parsing Error 3\n");
  }

  row2++;

}

// そして最後の記号は }\n でなければなりません

4

1 に答える 1

0

あなたのアルゴリズムはすでに壊れています。のまったく同じ内容を使用し*file_stringて、2 つの異なる文字列と比較します。に一致するものが見つかった場合は"readEveryLine"、次の に一致するものを取得する前に、ファイルから次の行を読み取る必要がありますstrncmp()。それ以外の場合、ファイルの行は と の両方"readEveryLine" "{"一致し、2 番目の条件に合格する必要がありますifが、これは不可能です。

編集:いくつかの改善を行ったので、あなたのアプローチではうまくいかないと思います。ループは必要なときに終了せず、if-else-cascade も良い考えではないようです。あなたのアプローチでは、1行だけを解析する必要があるのに、あまりにも多くの行を読むことに混乱します。

ステートマシンについて少し読んだほうがいいかもしれません。

これは、私が問題に対処する方法を簡単に示したものです。

enum { STATE_HEADER1, STATE_HEADER2, STATE_BODY, STATE_END} state;
int done = 0;
state = STATE_HEADER1;

while (fgets(buffer, MAX_PARSING, fp) && !done) {        
  if (state == STATE_HEADER1) {
    if (strcmp(buffer, "readEveryLine\n") == 0) {
      printf("%s", buffer);
      state = STATE_HEADER2;
    }
    else {
      printf("Parsing Error 1\n");
      done = 1;
    }        
  }
  else if (state == STATE_HEADER2) {
    if (strcmp(buffer, "{\n") == 0) {
      printf("%s", buffer);
      state = STATE_BODY;
    }
    else {
      printf("Parsing Error 2\n");
      done = 1;
    }
  }
  else if (state == STATE_BODY) {
    if (strcmp(buffer, "  ") == 0) {
      const char *p1 = strstr(buffer, "\"");
      const char *pm = strstr(p1, " [m]\"");
      const char *pf = strstr(p1, " [f]\"");
            char *res;
      const char *ptemp;
      int is_male;

      if (p1 && pf)  {
        p1 ++;
        is_male = 0;
        size_t len1 = pf - p1;
        res = malloc(len1 + 1);
        strcpy(res, p1);
        ptemp = pf+3; // point after closing \"

        // give res for functionFemale() to work on that string
      }
      else if (p1 && pm) {
        p1 ++;
        is_male = 1;
        size_t len1 = pm - p1;
        res = malloc(len1 + 1);
        strcpy(res, p1);
        ptemp = pm+3; // point after closing \"

        // give res for functionMale() to work on that string
      }
      else {
        done = 1;
        printf("Parsing Error 2\n");
      }

      // Now we have res and is_male holding name and gender.

      if (!done)
      {
        if (strncmp(ptemp, " -> ", 4) == 0) {

  // Handle this variant:
  // this sign can either exist like this:
  // "Bart [m]" -> "Marge [f]";

          // Do similar stuff as above for first name

          // Get second name + gender
          // Also check trailing ';' here
        }
        else if (strcmp(temp, ";\n") == 0) {

 // Handle this variant:
 // or like this:
 // "Marge [f]";

        }

      } // found "  "
      else {
        if (strcmp(buffer, "}\n") == 0) {
          state = STATE_END;
          done = 1;
          printf("That's it folks...\n"); 
        }
        else {
          done = 1;
          printf("Parsing Error 3\n");
        }
      }
    }
  } // STATE_BODY
} // while (fgets)

if (state == STATE_END) }
  // Success. :)
} else {
  // Something didn't match.
}

// close file, cleanup, etc.

まだコンパイルしていませんが、アイデアは得られるはずです。

于 2017-01-02T15:58:25.793 に答える