2015-02-01 2 views
1

다음 두 함수를 만들었습니다. 먼저, eatWrd은 어떠한 공백이없는 문자열의 첫 번째 단어를 반환하고, 상기 입력 문자열에서 첫 번째 단어를 제거 :문자열의 첫 번째 단어를 반환하려고하는 두 개의 C 함수

MAX 문자열의 최대 길이를 나타내는 숫자이다

char* eatWrd(char * cmd) 
{ 
    int i = 0;  //i will hold my place in cmd 
    int count = 0; //count will hold the position of the second word 
    int fw = 0;  //fw will hold the position of the first word 
    char rest[MAX]; // rest will hold cmd without the first word 
    char word[MAX]; // word will hold the first word 

    // start by removing initial white spaces 
    while(cmd[i] == ' ' || cmd[i] == '\t'){ 
    i++; 
    count++; 
    fw++; 
    } 

    // now start reading the first word until white spaces or terminating characters 
    while(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '\n' && cmd[i] != '\0'){ 
    word[i-fw] = cmd[i]; 
    i++; 
    count++; 
    } 
    word[i-fw] = '\0'; 

    // now continue past white spaces after the first word 
    while(cmd[i] == ' ' || cmd[i] == '\t'){ 
    i++; 
    count++; 
    } 

    // finally save the rest of cmd 
    while(cmd[i] != '\n' && cmd[i] != '\0'){ 
    rest[i-count] = cmd[i]; 
    i++; 
    } 
    rest[i-count] = '\0'; 

    // reset cmd, and copy rest back into it 
    memset(cmd, 0, MAX); 
    strcpy(cmd, rest); 

    // return word as a char * 
    char *ret = word; 
    return ret; 
} 

둘째, frstWrd, 그냥 입력 문자열 수정하지 않고 첫 번째 단어를 반환

// this function is very similar to the first without modifying cmd 
char* frstWrd(char * cmd) 
{ 
    int i = 0; 
    int fw = 0; 
    char word[MAX]; 

    while(cmd[i] == ' ' || cmd[i] == '\t'){ 
    i++; 
    fw++; 
    } 

    while(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '\n' && cmd[i] != '\0'){ 
    word[i-fw] = cmd[i]; 
    i++; 
    } 
    word[i-fw] = '\0'; 

    char *ret = word; 
    return ret; 
} 

이 기능을 테스트하려면, 나는 사용자에서 (나) 문자열을 읽을 수는 fgets를 사용하고, 나는이 세 가지 문자열을 인쇄 (frstWrd (입력), eatWrd (입력), eatWrd (입력)). 예를 들어 "my name is tim"이라는 문자열이 주어지면 프로그램은 "my my name"을 인쇄하지만 "is is"는 세 번째 단어를 "is is is"라고 인쇄합니다 :

나는 내 기능을 반복해서 들여다 보았고 그 실수를 볼 수 없다. 나는 printf에 관해서 모르는 무언가가 있거나, 다른 함수에서 인수로 여러 개의 문자열 수정 함수를 사용한다고 생각한다. 어떤 통찰력이라도 도움이 될 것입니다.

+0

돌출 문제를 설명하는 하나 개의 긴 단락 읽기 어렵다 . 어떻게 든 정보를 분할하십시오. – bolov

+2

관련 :'printf()'인수에 세 함수 호출의 실행 순서에 대한 보장이 있는지 궁금하게 생각해야합니다. (스포일러 : 그런 보장은 없습니다). 그리고 반환 값에 명확하게 * 정의되지 않은 동작 *이 있습니다 (아래의 Volands 응답 참조). – WhozCraig

+0

ty, 나는 개인적으로 훨씬 나아 졌다고 생각합니다. – bolov

답변

1

마찬가지로 restword은 함수 의 로컬 변수입니다. 따라서 함수 외부에서 그러한 메모리에 대한 포인터를 반환하는 것은 나쁜 습관입니다.

편집 1 :

이 또한 이해한다, 라인

printf("%s %s %s", frstWrd(input), eatWrd(input), eatWrd(input)); 

기능 eatWrd(input)에 (frstWrd(input) 전) 첫 번째 호출 할 수 있었다.

편집 2 :

int main() 
 
{ 
 
    char input[MAX]; 
 
    fgets(input, MAX - 1, stdin); 
 
    printf("%s ", frstWrd(input)); 
 
    printf("%s ", eatWrd(input)); 
 
    printf("%s\n", eatWrd(input)); 
 
}
,536 :

이는 수 finction eatWrd

//char rest[MAX]; // rest will hold cmd without the first word 
 
    char * rest = (char*) malloc(MAX);

그리고 새로운 주요하자에 유용 할 수 있습니다

그리고 결국 frstWrd 내 솔루션 (단지 유용 할 수있는 방법을 표준 기능을 보여주기) :

char* frstWrd(char * cmd) 
 
{ 
 
    char * word = (char *) malloc(MAX); 
 
    sscanf(cmd, "%s", word); 
 
    return word; 
 
}

+0

그래, 고마워, 그래서 어떤 좋은 방법은 C 함수에서 문자열을 반환 무엇입니까? – quigs

+0

@quigs 문자열에 필요한 메모리를'malloc()'하여 반환 할 수도 있습니다. 이 접근법의 가장 큰 장점은 주어진 크기의 미리 할당 된 버퍼를 사용할 필요가 없다는 것입니다. 대신 문자열을 저장하기 위해 메모리를 할당해야합니다. 이것은 거대한 에러 소스를 제거합니다. malloc으로 묶인 문자열 (asprintf(), strdup() 등)을 반환하는 표준 함수 (POSIX-2008 표준)가 이미 있으므로이 방법이 훨씬 편리합니다. 이들은 일반적으로 무거운 짐을하는 데 사용할 수 있습니다. 기억할 필요가있는 것은'free()'호출뿐입니다. – cmaster

+0

@quigs : char * return 포인터 유형의 함수이며 함수가 끝난 후에 사용할 수있는 메모리를 사용하기 위해 매우 importnt합니다. 따라서 세 가지 옵션이 있습니다 : a) 힙에서 메모리 사용 (malloc 또는 유사한 함수로 할당); b) 정적 로컬 변수를 사용합니다 (메모리는 예약되어 있고 함수가 작동하는 동안 사용할 수 있습니다). c) 전역 변수 나 외부에 할당 된 메모리 (예 : 사용자의 경우 cmd가 가리키는 메모리)가있는 메모리로 포인터를 반환합니다. – VolAnd

관련 문제