2017-01-02 19 views
0

에 strncmp와 각 행을 비교 :이는 fgets와 파일에서 라인을 읽고 나는 이런 식으로 뭔가 보이는 파일에서 모든 라인을 읽을 수 C

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

내가 사용하려는를 :

  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"); 
    } 
} 

그렇게 문제가 그냥 나에게 오류 구문 분석을 제공하고 내가 잘못 여기에 무슨 짓을했는지 모르겠어요 것입니다.

나를 도와 주셔서 감사합니다.

여기에 나는 지금 몇 가지를 만들었습니다. (처음 두 줄을 파싱하면됩니다.) 어쩌면 누구든지 저를 위해서 좋은 조언을 얻었을 것입니다. 고마워요.

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

+0

1)'string'과'changeLastC()'의 정의를 정의하십시오. 2) 컴파일러 경고가 완전히 활성화되도록하십시오. 3)''readEveryLine \ n "'이"readEveryLine "'과 같을 까 기대하는 이유는 무엇입니까? 그렇지 않으면 문제가 잘 정의되어 있지 않습니다. – chux

+2

왜 당신은'strncmp'를 사용하고 싶습니까? 이 목적을위한 올바른 함수는'strcmp '입니다. – rici

+0

@chux, 줄 끝에 '\ n'이 없습니다. 주석에 따르면'\ n'은'changeLastC() '함수에 의해'\ 0'으로 변경됩니다. – Gerhardh

답변

0

는 귀하의 알고리즘은 이미 나뉩니다. *file_string과 동일한 내용을 사용하여 다른 문자열과 비교하십시오. "readEveryLine"에 대한 일치 항목을 찾으면 strncmp()에 대한 다음 일치 항목을 얻기 전에 파일에서 다음 줄을 읽어야합니다. 그렇지 않으면 파일의 라인이 "{" 두 번째를 통과해야만 두 번째 if 조건을 충족해야합니다. 이는 불가능합니다.

편집 : 지금까지 몇 가지 개선 사항을 수행했지만 여전히 사용자의 접근 방식으로는 작동하지 않을 것이라고 생각합니다. 루프는해야 할 때 루프가 종료되지 않으며 if-else-cascade도 좋은 생각으로 보이지 않습니다. 당신의 접근 방식에서는 너무 많은 라인을 읽는 것에 엉망이 될 것입니다. 단 하나의 라인 만 파싱되어야합니다.

상태 시스템에 대해 조금 읽어야 할 수도 있습니다.

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. 

가 아직 컴파일하지 않았다하지만 당신은 아이디어를 얻을해야합니다

는 여기에 내가 문제를 해결 얼마나 빠른 방법입니다.

+0

소리가 분명합니다. 문제는, 다음 줄을 파싱하고, 조건을 다른 것으로 만들고, 세 번째 줄을 파싱하고, 조건을 다음으로 만드는 등의 방법을 모르는 것입니다. 도와 주셔서 정말로 고맙습니다. – MBD

+0

예를 들어 while (fgets (file_string, 19, file))과 같은 while 루프를 사용하고 첫 줄에이 버퍼를 사용하면 각 줄과 새 버퍼에 루프를 사용해야하는지 잘 모르겠습니다. 나는 이것이 잘못된 것이라고 생각한다. 도와 주셔서 정말로 고맙습니다. – MBD

+0

의사 코드로 시도해보십시오. 고무 오리 나 애완 동물에게 설명하려고하십시오. 당신은 또한 종이에 그것을 시도 할 수 있습니다. "first ..., then ..."과 같은 문구가 있으면 일련의 별도 동작이 필요합니다. 루프가 없습니다. "For every line ...."과 같은 문구가 있으면 루프가 필요합니다. 이것으로 파일의 처음 2 줄에는 루프가 필요 없다는 것을 분명히해야합니다. 하지만 다음 줄에는 루프가 필요합니다. 그리고 마지막 행 ("\ n")에 대한 일부 handlnig. 나는 당신이 C 텍스트 책을 다시 파헤 치고 _when_와 _how_ loops가 조금 더 많이 사용되는 것을 제안한다. – Gerhardh