Dayton Rumbold
Dayton Rumbold

Reputation: 88

Reading line count with strtok in c

For my program I must give the word and line count of a file. I know their is an easier way to do it using if statements but I am required to use strtock. It currently gives me a correct word count but my line count is consistently wrong.

Here's my code:

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

int wordcount(char *string);
int linecount(char *string);

int main(){
    char * buffer=0;
    long length;
    char filename[50];

    printf("Enter file name: \n");
    scanf("%s",filename);
    FILE *f= fopen(filename, "rb");

    if(f){
        fseek(f,0,SEEK_END);
        length=ftell(f);
        fseek(f,0,SEEK_SET);
        buffer=malloc(length);
        if (buffer){
            fread(buffer,1,length,f);
        }
        fclose(f);
    }
    if(buffer){
        printf("wordcount: %i\n", wordcount(buffer));
        printf("linecount: %i\n", linecount(buffer));
    }

    return (EXIT_SUCCESS);
}


int wordcount(char *string){
    int count=0;
    for(string=strtok(string," =.!,;\n");string; string=strtok(NULL, " -.!,;\n"))
        count++;
    return count;
}

int linecount(char *string){
    int count=1;
    for(string=strtok(string,"\n");string; string=strtok(NULL, "\n"))
        count++;
    return count;
}

I know I am missing something inside my strtok that isn't counting but I am not sure what it is. Any help is greatly appreciated.

Upvotes: 1

Views: 542

Answers (2)

money-for-nothing
money-for-nothing

Reputation: 21

You can't use strtok twice on the same string like that, strtok splits the string to several strings.
I recommend running strtok only on copies, preferably local ones.
Something like that:

int wordcount(char *input){
  char string[strlen(input) + 1];
  int count=0;
  strcpy(string, input);
  for(string=strtok(string," =.!,;\n");string; string=strtok(NULL, " -.!,;\n"))
    count++;
  return count;
}

int linecount(char * input){
  char string[strlen(input) + 1];
  int count=0;
  strcpy(string, input);
  for(string=strtok(string,"\n");string; string=strtok(NULL, "\n"))
    count++;
  return count;
}

Upvotes: 2

tttapa
tttapa

Reputation: 1417

strtok destroys the string, it writes null terminators.

If you want to use strtok, you have to make a copy of the string, and use strtok on the copy.

For example:

int wordcount(const char *string) {
    char *copy = malloc(strlen(string) + 1);
    strcpy(copy, string);
    int count = 0;
    for (copy = strtok(copy, " =.!,;\n"); copy; copy = strtok(NULL, " -.!,;\n"))
        count++;
    free(copy);
    return count;
}

int linecount(const char *string) {
    char *copy = malloc(strlen(string) + 1);
    strcpy(copy, string);
    int count = 0;
    for (copy = strtok(copy, "\n"); copy; copy = strtok(NULL, "\n"))
        count++;
    free(copy);
    return count;
}

Upvotes: 3

Related Questions