2011. 9. 2. 20:38

♧ strtok_r 함수를 이용해서 한 줄의 평균 단어 수를 구한다.

원형

double wordaverage(char *s);

인수

const char *s : 문자열 버퍼를 가리키는 포인터.

반환

double - 평균 단어 수.

 

strtok함수는 하나의 지역 변수만을 사용하기 때문에 여러 번에 걸쳐 호출하게 된다면

 문자열의 파싱은 서로 방해 받고 말 것이다.

☞ 그래서 멀티스레드 프로그램에서의 안전성을 위하여 strtok대신 strtok_r 함수를 사용.

strtok_r 에서 "_r" 표시는 재진입(reentrant)를 뜻하며,

 함수가 그 전의 호출이 끝나기 전에 재진입(재호출)될 수 있다는 것을 의미.

 

 

[ 예제 코드 : wordaveragetest.c ]

#include <stdio.h>
#include <unistd.h>

#define BUFSIZE	1024

extern double wordaverage(char *s);

int main() {
    char    buf[BUFSIZE];
    int	    size = 0;
    int	    num;
    double  ave;

    while (size < BUFSIZE-1) {
	num = read(0, buf+size, BUFSIZE-size-1);
	if (num == 0) break;
	if (num < 0) {
	    fprintf(stderr, "Error reading from standard input!\n");
	    return 1;
	}
	fprintf(stderr, "%d bytes read\n", num);
	size += num;
    }
    buf[size] = 0;
    fprintf(stderr, "Total number of bytes read = %d\n", size);
    ave = wordaverage(buf);
    fprintf(stderr, "The average number of word is %f\n", ave);

    return 0;
}

 

[ 예제 코드 : wordaverage.c ]

#include <string.h>
#define LINE_DELIMITERS	"\n"
#define WORD_DELIMITERS	" "

static int wordcount(char *s) {
    int   count = 1;
    char *lasts;

    if (strtok_r(s, WORD_DELIMITERS, &lasts) == NULL)
	return 0;
    while (strtok_r(NULL, WORD_DELIMITERS, &lasts) != NULL)
	count++;

    return count;
}

/* return average size of words in s */
double wordaverage(char *s) {
    char *lasts;
    char *nextline;
    int	  words;
    int   linecount = 1;

    nextline = strtok_r(s, LINE_DELIMITERS, &lasts);
    if (nextline == NULL)
	return 0.0;
    words = wordcount(nextline);
    while ((nextline = strtok_r(NULL, LINE_DELIMITERS, &lasts)) != NULL) {
	words += wordcount(nextline);
	linecount++;
    }
    return (double)words/linecount;
}

 

▶ 사용 예:

$ ./wordaverage

word1 word2 word3

18 bytes read

word4 word5

12 bytes read

word6 word7 word8 word9 word10

31 bytes read

Total number of bytes read = 61

The average number of word is 3.333333

 

Posted by devanix