0

I need to make a program that prompts the user for the name of two text files which will be read in and displayed on screen followed by their statistics, such as number of characters, words and lines. I've managed to get it all working apart from the statistics part. They don't seem to be counting up and I think it's something to do with the while statements that I've used. Any help would be great :)

code:

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

int main() {

    // declaring variables
    FILE *fp;
    int charcount = 0, wordcount = 0, linecount = 0;
    int character;
    char first[50];
    char second[50];
    char ch[200];

    // asking the user for the file names and scanning the names they enter as txt files
    printf(" Enter the first file name: ");
    scanf("%s", first);
    strcat(first, ".txt");

    printf(" Enter the second file name: ");
    scanf("%s", second);
    strcat(second, ".txt");

    // opening the file stream
    fp = fopen(first, "r");

    // if the file cannot be reached, display error
    if (fp == NULL) {
        printf("File cannot be opened: %s\n", first);
        return 0;
    }

    // reading and printing the file into the program
    printf("\n---FIRST FILE---\n");
    while (!feof(fp)) {
        fgets(ch, 200, fp);
        puts(ch);
    }

    // counting the characters, words and lines until the program is finished
    while ((character = getc(fp)) != EOF) {
        if (character == '-')
        {
            charcount++;
        }
        if (character == ' ')
        {
            wordcount++;
        }
        if (character == '\n')
        {
            linecount++;
        }
    }

    // closing the stream
    fclose(fp);

    // printing the number of characters, words and lines
    printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n\n", charcount, wordcount, linecount);

    //---------SECOND FILE----------//

    // opening the stream
    fp = fopen(second, "r");

    // reading and printing the file into the program
    printf("\n---SECOND FILE---\n");
    while (!feof(fp)) {
        fgets(ch, 200, fp);
        puts(ch);
    }

    // counting the characters, words and lines until the program is finished
    while ((character = getc(fp)) != EOF) {
        if (character == '-')
        {
            charcount++;
        }
        if (character == ' ')
        {
            wordcount++;
        }
        if (character == '\n')
        {
            linecount++;
        }
    }

    // closing the stream
    fclose(fp);

    // printing the number of characters, words and lines
    printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n", charcount, wordcount, linecount);

}
Tim
  • 4,790
  • 4
  • 33
  • 41
rozak
  • 41
  • 1
  • 7
  • 2
    Welcome to Stack Overflow! It sounds like you may need to learn how to use a debugger to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Paul R Dec 05 '16 at 19:10
  • 2
    See: [Why is “while ( !feof (file) )” always wrong?](http://stackoverflow.com/questions/5431941/why-is-while-feof-file-always-wrong). – Paul R Dec 05 '16 at 19:11
  • You need `rewind(fp);` before 2nd while-loop. Also `puts(ch);` --> `fputs(ch, stdout);` – BLUEPIXY Dec 05 '16 at 19:11
  • 1
    This would be an excellent opportunity for you to learn to use a debugger, so you can step through the code and see *exactly* what code is (and is not) executed. – Ken White Dec 05 '16 at 19:11
  • You could use `fgets` to count the lines and characters, and then use a `strtok` loop to isolate (and count) words. – Weather Vane Dec 05 '16 at 19:20
  • 1
    Welcome to Stack Overflow! Please see [How to create a Minimal, Complete, and Verifiable Example](/help/mcve). – MD XF Dec 05 '16 at 19:32
  • @BLUEPIXY I've done this and it still won't correctly read the number of characters, words or lines. Do you have any more ideas? – rozak Dec 05 '16 at 21:03
  • you count `-` as characters and `' '` as word. It is necessary to change it. – BLUEPIXY Dec 05 '16 at 21:05
  • @BLUEPIXY i don't quite understand what I should be changing them to... is the rest of the code correct and that is the only part I have wrong? – rozak Dec 05 '16 at 22:28
  • I think so. If there is an input sample and the expected output, we may be able to match the idea. – BLUEPIXY Dec 05 '16 at 22:35
  • @BLUEPIXY input: http://prntscr.com/dft5u5 output: http://prntscr.com/dft5pe It's counting everything completely wrong, the only thing that is right is the character count for the first file. – rozak Dec 05 '16 at 22:42
  • The input as I say is the contents of the file. Also, please add to the question by text rather than image. – BLUEPIXY Dec 05 '16 at 22:48
  • Can you please show me what you mean.. I really don't understand why this thing isn't working @BLUEPIXY – rozak Dec 05 '16 at 22:51
  • 1) The reason that the number of words is different is counting space. 2) The reason for the number of rows is probably because newline may not exist at the end of the file. or `while(!eof(fp))` – BLUEPIXY Dec 05 '16 at 22:51
  • @BLUEPIXY I got it to work finally! Thank you so much for the help! :) – rozak Dec 05 '16 at 23:04

3 Answers3

0

Imagine that you're using one of those text editors to open your file and moving the caret/cursor is the only way to navigate. Your first goal is to navigate through the whole content and display it. That's what the loop below does:

while(!feof(fp)){
    fgets(ch, 200, fp);
    puts(ch);
}

The !feof(fp) moved the cursor to the end of the file so you could read it all.

If you have to count chars then you need to navigate back to somewhere in your file. Since you want statistics from the whole txt, then you could simply use rewind(fp) or fseek(fp, 0, SEEK_SET) before your second loop to move the cursor back to the begin.

I recommed using fseek() because it will clear the end of file indicator. Take a closer look here.

  • Thank you so much for the help! I've added the fseek(fp, 0, SEEK_SET) just before the 2nd while loop that contains the if statements however it still isn't managing to count the characters, words or lines correctly. Any more ideas? – rozak Dec 05 '16 at 20:47
0

I finally got it to work, if anyone is interested the final code is here:

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

int main() {

    // declaring variables
    FILE *fp;
    int charcount = 0, wordcount = 0, linecount = 1;
    int charcount2 = 0, wordcount2 = 0, linecount2 = 1;
    int character;
    char first[50];
    char second[50];
    char ch[200];

    // asking the user for the file names and scanning the names they enter as txt files
    printf(" Enter the first file name: ");
    scanf("%s", first);
    strcat(first, ".txt");

    printf(" Enter the second file name: ");
    scanf("%s", second);
    strcat(second, ".txt");

    // opening the file stream
    fp = fopen(first, "r");

    // if the file cannot be reached, display error
    if (fp == NULL) {
        printf("File cannot be opened: %s\n", first);
        return 0;
    }

    // reading and printing the file into the program
    printf("\n---FIRST FILE---\n");
    while (!feof(fp)) {
        fgets(ch, 200, fp);
        fputs(ch, stdout);
    }

    // counting the characters, words and lines until the program is finished
    fseek(fp, 0, SEEK_SET);
    while ((character = fgetc(fp)) != EOF) {
        if (character == EOF)
            break;
        {
            charcount++;
        }
        if (character == ' ' || character == '.')
        {
            wordcount++;
        }
        if (character == '\n')
        {
            linecount++;
        }
    }

    // closing the stream
    fclose(fp);

    // printing the number of characters, words and lines
    printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n\n", charcount, wordcount, linecount);

    //---------SECOND FILE----------//

    // opening the stream
    fp = fopen(second, "r");

    // reading and printing the file into the program
    printf("\n---SECOND FILE---\n");
    while (!feof(fp)) {
        fgets(ch, 200, fp);
        fputs(ch, stdout);
    }

    // counting the characters, words and lines until the program is finished
    fseek(fp, 0, SEEK_SET);
    while ((character = getc(fp)) != EOF) {
        if (character == EOF)
            break;
        {
            charcount2++;
        }
        if (character == ' ' || character == '.')
        {
            wordcount2++;
        }
        if (character == '\n')
        {
            linecount2++;
        }
    }

    // closing the stream
    fclose(fp);

    // printing the number of characters, words and lines
    printf("\n Characters: %d \n Words: %d\n Lines: %d\n\n", charcount2, wordcount2, linecount2);

}
rozak
  • 41
  • 1
  • 7
0

counting sample

#include <stdio.h>
#include <ctype.h>

typedef struct statistics {
    size_t charcount, wordcount, linecount;
} Statistics;

Statistics count_cwl(FILE *fp){
    size_t c = 0, w = 0, l = 0;
    int ch;
    char prev = ' ';

    while((ch = getc(fp)) != EOF){
        ++c;
        if(isspace(prev) && !isspace(ch)){
            ++w;//need to delete punctuation marks ?
        }
        if(ch == '\n'){
            ++l;
        }
        prev = ch;
    }
    if(prev != '\n')//There is no newline at the end of the file
        ++l;
    return (Statistics){ c, w, l};
}

int main(void) {
    char filename[50] = "test.c";
    FILE *fp = fopen(filename, "r");

    if (fp == NULL) {
        printf("File cannot be opened: %s\n", filename);
        return -1;
    }

    Statistics stat = count_cwl(fp);

    fclose(fp);

    printf("\nCharacters: %zu\nWords: %zu\nLines: %zu\n", stat.charcount, stat.wordcount, stat.linecount);
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70