为什么strtok()在C中将单词和限制单词分成7个字符?

时间:2013-03-06 00:23:34

标签: c

过去两天我到处搜寻,无法弄清楚这一点。以下是输出的一小部分示例:

应该读“并找到乐趣”:

˚F

IND

P

利热

=====

长度计数

=====

1 9054

2 10102

3 9336

4 5944

5 3311

6 1656

7 1292

=====

平均2.86

=====

以下是代码:

#include <stdio.h>
#include <stdlib.h>
#include<string.h>

#define DELIM " ,.;:'\"&!? -_\n\t\0"

int process(int *count, char *buffer);
int printOut(int *count);

int main() {
    char *buffer = (char *) calloc(1, 50*sizeof(char*));
    int *count =(int*) calloc(50, 50*sizeof(long));

    while (fgets(buffer, sizeof buffer, stdin)) {
        process(count, buffer);
    }

    printOut(count);
    free(count);
    return 0;
}

int process(int *count, char *buffer) {
    int word_len=0, i;
    char *pch;
    pch = strtok(buffer, DELIM);
    while (pch != NULL) {
        for(i=0; pch[i] != '\0'; i++) {
                word_len++;
        }
        count[word_len]++;
        word_len=0;
        printf("%s\n", pch);
        pch = strtok(NULL, DELIM);
    }
    return 0;
}

int printOut(int *count) {
    int i;
    double num=0;
    double total=0;
    double average=0;
    printf("================\n");
    printf("len  count\n");
    printf("================\n");
    for(i=0;i<50;i++){
        if(count[i]!=0){
            num=count[i]+num;
            total=total+(count[i]*i);
            printf("%d   %d\n",i,count[i]);
        }
    }
    average = total/num;
    printf("================\n");
    printf("average %.2f\n", average);
    printf("================\n");
    return 0;
}

3 个答案:

答案 0 :(得分:3)

这是错误的:

 char *buffer = (char *) calloc(1, 50*sizeof(char*));

应该是:

 sizeof(char) // or since this is always 1: 'calloc(1, 50)'

但真正的问题在于:

fgets(buffer, sizeof buffer, stdin);

sizeof缓冲区是4(或者指针的大小),因为它是一个指针,你需要这样做:

fgets(buffer, 50, stdin);

sizeof(long)的calloc调用中的count也不是那样,你需要sizeof(int),否则你可能会分配更多的字节然后你想要(取决于建筑)。所以这可以是:

int *count =(int*) calloc(50, sizeof(int));

答案 1 :(得分:0)

int main() {
    char *buffer =  calloc(50, 1);
    int  *count  =  calloc(50, sizeof(int));

    while (fgets(buffer, 50, stdin)) {
        process(count, buffer);
    }

你的原始fgets只“读取”sizeof指针:4或8字节,而不是entery缓冲区,或50 char,是你想要的。

答案 2 :(得分:0)

这个反例可能会有所帮助:

/*
 * Sample output:
 *   word= and, length(word)= 3
 *   word= find, length(word)= 4
 *   word= a, length(word)= 1
 *   word= pleasure, length(word)= 8
 *   Done.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUF_LEN 50
#define DELIM " ,.;:'\"&!? -_\n\t\0"

void process(int *count, char *buffer);

int main() {
  char buffer[BUF_LEN];
  int count[BUF_LEN];

  strcpy (buffer, "and find a pleasure");
  process(count, buffer);

  printf ("Done.\n");
  return 0;
}

void process(int *count, char *buffer) {
  char *pch = strtok(buffer, DELIM);
  while (pch) {
    printf ("word= %s, length(word)= %d\n",
      pch, strlen(pch));
    pch = strtok (NULL, DELIM);
  }
}