2014-11-12 4 views
-1

단어를 시도하고 검색하기 위해 char 배열 문자열을 반복하는 코드 조각이 있습니다. 루프가 끝나고 A - Z 또는 - z 또는 _ (밑줄)을 감지하면 문자 배열에 추가됩니다. 내가 필요한 것은 단어이기 때문에 다른 함수를 사용하여 폐기 할 수있는 문자열에 넣을 수 있습니다. 이 제 기능입니다 : 그것은 별도의 라인을 출력합니다 때문에이 모든 단어를 볼 수있는 순간C 언어의 문자 배열에서 문자열 만들기

char wholeProgramStr2[20000]; 
char wordToCheck[100] =""; 

IdentiferFinder(char *tmp){ 
    //find the identifiers 
    int count = 0; 
    int i; 
    for (i = 0; i < strlen(tmp); ++i){ 
     Ascii = toascii(tmp[i]); 
     if ((Ascii >= 65 && Ascii <= 90) || (Ascii >= 97 && Ascii <= 122) || (Ascii == 95)) 
     { 
      wordToCheck[i] = tmp[i]; 
      count++; 
      printf("%c",wordToCheck[i]); 
     } 
     else { 
      if (count != 0){ 
      printf("\n"); 
     } 
      count = 0; 
     } 
    } 
    printf("\n"); 
} 

.

WholeProgram2의 내용은 파일의 모든 행과 동일합니다. * tmp 인수입니다.

감사합니다.

+4

마법 번호와 비교하지 마십시오. 'isalpha()'와''-''를 사용하십시오. – unwind

+0

귀하의 질문은 [this one] (http://stackoverflow.com/questions/308695/how-to-html)과 중복되는 [this one] (http://stackoverflow.com/q/26869798/841108)과 유사합니다. concatenate-const-literal-strings-in-c). [내 대답] (http://stackoverflow.com/a/26869883/841108)을 필요에 맞게 수정하십시오. –

+0

현재'wordToCheck' 배열을 채 웁니다 (그러나'= ""이니셜 라이저를 제거합니다. 전역 변수는'zero initialized '입니다.) 그래서'tmp'가 너무 길지 않다면 배열에 NUL 종료 문자열을 얻을 것입니다.) 전역 변수이므로 다른 함수에서 액세스 할 수 있습니다. 원하는 것을 명확히하거나 문제가 무엇인지 명확히하십시오. – Jite

답변

3

큰 문자열을 작은 문자열 (단어)로 분리하여 설명합니다. 당신을 가정
는 공백이나 탭이나 줄 바꿈으로, 구문 분석하는 일반적인 구분 기호를 사용하고 있습니다 :
먼저는, 소스 문자열에 대한 정보를 얻을 :

여기

는 세 단계 접근에게 있습니다.
둘째, 당신의 크기는 문자열의 대상 배열을 채울 strtok()
셋째, 루프를 필요에 맞게 동적으로 대상 배열을 생성 (문자 **)

(A 등이 될 것이다 생성 된 메모리를 해제하려면, 당신이해야 할 것입니다)
힌트 : 프로토 타입은 다음과 같이 보일 수 있습니다 :
// void Free2DCharArray (char ** a, int numWords);

코드 예제 :

void FindWords(char **words, char *source); 
void GetStringParams(char *source, int *longest, int *wordCount); 
char ** Create2DCharArray(char **a, int numWords, int maxWordLen); 
#define DELIM " \n\t" 

int main(void) 
{ 
    int longestWord = 0, WordCount = 0; 
    char **words={0}; 
    char string[]="this is a bunch of test words"; 

    //Get number of words, and longest word, use in allocating memory 
    GetStringParams(string, &longestWord, &WordCount); 

    //create array of strings with information from source string 
    words = Create2DCharArray(words, WordCount, longestWord); 

    //populate array of strings with words 
    FindWords(words, string); 

    //Do not forget to free words (left for you to do) 
    return 0; 
} 

void GetStringParams(char *source, int *longest, int *wordCount) 
{ 
    char *tok; 
    int i=-1, Len = 0, KeepLen = 0; 
    char *cpyString = 0; 
    cpyString = calloc(strlen(source)+1, 1); 
    strcpy(cpyString, source); 
    tok=strtok(source, DELIM); 
    while(tok) 
    { 
     (*wordCount)++; 
     Len = strlen(tok); 
     if(Len > KeepLen) KeepLen = Len; 
     tok = strtok(NULL, DELIM); 
    } 
    *longest = KeepLen; 
    strcpy(source, cpyString);//restore contents of source 
} 

void FindWords(char **words, char *source)    
{ 
    char *tok; 
    int i=-1; 

    tok = strtok(source, DELIM); 
    while(tok) 
    { 
     strcpy(words[++i], tok); 
     tok = strtok(NULL, DELIM); 
    } 
} 

char ** Create2DCharArray(char **a, int numWords, int maxWordLen) 
{ 
    int i; 
    a = calloc(numWords, sizeof(char *)); 
    if(!a) return a; 
    for(i=0;i<numWords;i++) 
    { 
     a[i] = calloc(maxWordLen + 1, 1);  
    } 
    return a; 
} 
2

당신의 목표는 문자의 배열에서 단어를 찾을 경우, 당신은 아마 첫 번째 문자의 올바른 순서를 (찾으려하고 당신이 시도 될 것으로 보인다 그 일을하기 위해서), 하나를으로 찾았 으면, 그 실제 단어인지를 2 차 점검하십시오. 실제로 단어 인 경우 추가 사용을 위해 보관할 수 있습니다.

이 접근법의 장점은 사전에있는 가장 큰 단어와 일치하는 크기의 잠재적 인 단어의 큰 버퍼를 유지할 필요가 없다는 것입니다. 사실 버퍼를 필요로하지 않고, 문자 배열을 따라 슬라이딩하는 포인터, 가능한 단어의 시작을 가리키는 포인터, int (바이트로 충분할 수도 있음)를 사용하여 해당 단어의 길이를 추적 할 수 있습니다.

// structure to store a word match in array 
typedef struct token_s { 
    int length; 
    const char *data; 
} token_t; 

void nextToken(const char *tmp, int len, token_t *to){ 
    char *start = NULL; 
    while (len){ 
    if (start) { 
     // search for end of current word 
     if (!isalpha(*tmp)) { 
     to->data = start; 
     to->length = tmp - start; 
     return; 
     } 
    } else { 
     // search for beginning of next word 
     if (isalpha(*tmp)) 
     start = tmp; 
    } 
    tmp++; 
    len--; 
    } // while 
    if (start) { 
    to->data = start; 
    to->length = tmp - start; 
    } 
} 

간단히 통과 :

  • 당신의 문자 배열의 시작, 또는 to->data + to->length + 1 그것을 배열
  • 의 끝을지나 아니라면 char 배열의 비가 길이는
  • 를 스캔 0을 가리키는 포인터 token_t

nextToken이고 후보자를 찾았는지 알기 위해 토큰의 내용을 확인하십시오. 그렇지 않은 경우 배열이 완전히 스캔되었음을 알 수 있습니다.

void scanArray(const char *tmp, int len){ 
    while (len > 0){ 
    token_t to; 
    to.data = NULL; 
    to.length =0; 
    nextToken(tmp, len, &to); 
    if (to.data) { 
     tmp += to.length +1; 
     len -= to.length +1;  
     // process token here... 
    } else break; 
    } // while 
} 

나는 유효한 문자를 테스트하는 isalpha를 사용하지만, 당신은 당신의 자신의 기능에 의해 그것을 대체 할 수 있습니다. scanArray의 본문에 보조 검사를위한 코드를 삽입해야합니다.

관련 문제