2016-10-06 2 views
-2

저는 C와 포인터를 처음 사용하기 때문에 지옥처럼 혼란 스럽습니다! 다음은 단어가 텍스트 파일에 나타나는 횟수를 찾는 주된 목적을 가진 함수 코드입니다. 어떤 도움을 주시면 감사하겠습니다! 스트림에 부착 된 문자 기반 상태 머신 - - 더 큰 문제로 확장되지 않습니다C에서 텍스트 파일에 단어가 나타나는 횟수 검색

void count_occurrences (int n, FILE *file, Entry *entries) { 
    file = fopen("test/flicka.txt", "r"); 
    if (file != NULL) { 
     char buff[LINE_MAX_CHARS]; 
     int i = 0; 
     char * haystack = fgets(buff, 1000, file); 
     char * needle = NULL; 
     char * p = NULL; 
     while (haystack != NULL) { 
      for (i; i < n; i++) { 
       needle = entries[i].string; 
       while ((p = strstr(haystack, needle)) != NULL) { 
        entries[i].count++; 
        p++; 
       }  
      } 
      haystack = fgets(buff, 1000, file); 
      i = 0; 
     } 
     fclose(file); 
    } 
    else { 
     printf("File not found!\n"); 
    } 
} 
+0

같은 haystack을 계속해서 계속해서 검색합니다. 이미 검색 한 건초 더미를 건너 뛸 필요가 있습니다. 한 공간에서 검색을 이동하려면'p ++;'는'haystack = p + 1; '이어야합니다. 이렇게하면 "aaa"가 "aaaaa"와 3 번 일치합니다. 'haystack = p + strlen (needle);'과 같이 매치 시키길 원한다면, 루프 밖에서'strlen (needle) '을 한번 계산할 수 있다는 것을 제외하고는. –

+0

또한 이미 열려있는'FILE *'을 함수로 전달하거나, 지역 변수'FILE * file'을 사용하고 함수에서 파일을 열고 닫는 것에 주목하십시오. 'FILE * file'을 함수에 전달하지 않고 파일을 열어 무시합니다. 물론, 호출 코드에서'FILE * '의 복사본을 해치지는 않지만 무의미하다. (그리고 아마도 파일 이름을 매개 변수 ('const char * filename')로 넘기는 것보다는 하드 와이어로 만드는 것이 더 좋을 것입니다. 반복하겠습니다.) –

+0

조나단에게 도움을 주셔서 감사합니다. 인수 (FILE * 파일)로 주어진 포인터를 사용하여 함수에서 파일을 어떻게 열 수 있습니까? – Nick

답변

0

이 같은 운동의 문제는 특정 문제를 해결하는 가장 좋은 방법이다.

첫 번째 방법은 처음에 "구문 분석 위치"를 유지하는 것입니다. 그런 다음 데이터가 없어 질 때까지 fgetc()를 루프에서 호출하고 EOF를 얻습니다. 문자가 구문 분석 위치의 문자와 일치하는 경우 구문 분석 위치를 증가 시키십시오. 구문 분석 위치가 문자열의 끝으로 이동하면 일치하는 문자가 있으므로 증가시킵니다. 그렇지 않으면 첫 번째 문자가 일치하는지 여부에 따라 구문 분석 위치를 0 또는 1로 재설정하십시오.

첫 번째 방법은 빠르고 쉽지만 유연성이 없습니다.

더 많은 확장 가능한 방법은 온라인 기반 입력입니다. 라인이 짧아야한다는 것을 안다면 커다란 버퍼로 fgets를 호출하거나, 라인이 제한되지 않으면 "getline"을 빌드하십시오. 그런 다음 strstr을 호출하여 일치하는 항목이 있는지 확인합니다. 일치하는 항목이 있으면 포인터를 증가시키고 다른 포인터를 확인해야합니다.

확장 가능한 방식은 구문 분석을 IO와 분리하고 여러 패턴을 검색 할 수있게 해줍니다. 의사 코드

while(line = getline()) 
{ 
    N += countwords(line, "myword"); 
} 

int countwords(line, word) 
{ 
    ptr = line; 
    while(strstr(ptr, word)) 
    { 
    ptr = strstr(ptr, word) + strlen(word); // replace strlen with 1 to allow overlaps 
    answer++; 
    } 
} 

은 분명히 당신은 지금 NS 개의 배열을 유지하고 각 단어 반복 호출 여러 단어를 검색하는 메인 루프를 수정해야합니다. 그러나 어떤 종류의 패턴 일치로도 확장됩니다.

관련 문제