1. Counting characters
/* Description:
* Counts the number of characters existing in the file specified by @stream.
* Parameters:
* stream - a pointer to a text file
* Returns:
* The number of characters in the file.
* Postconditions:
* The file pointer will be positioned at the end of the stream.
*/
long CountCharacters(FILE* stream)
{
long counter = 0L;
char c = 0x01;
/*Counts until the cursor reaches EOF*/
while(c!=EOF)
{
c = fgetc(stream);
counter++;
}
return counter;
}
The function will return a long variable in order to avoid possible counter overflows caused by large files. The char variable c is initialized to an arbitrary variable so I could use a while loop instead of a do/while loop. The loop will be exited when the file cursor will reach the EOF (End of File) character.
2. Counting Lines
/* Description:
* Counts the number of lines existing in the file specified by @stream.
* Parameters:
* stream - a pointer to a text file
* Returns:
* The number of lines in the file.
* Postconditions:
* The file pointer will be positioned at the end of the stream.
*/
long CountLines(FILE* stream)
{
/*The counter is initialized to 1 because it will not count the first
line*/
long counter = 1L;
char c = 0x01;
/*Counts until the cursor reaches EOF*/
while(c!=EOF)
{
c = fgetc(stream);
/*Checks if it encounters and a newline character*/
if(c=='\n')
{
counter++;
}
}
return counter;
}
The same rules apply as above with the exception that the counter starts at 1 in order to include the first line. Also, the counter is only incremented when an '\n' (newline) character is encountered.
3.Counting Words
/* Description:
* Counts the number of words existing in the file specified by @stream.
* Parameters:
* stream - a pointer to a text file
* Returns:
* The number of words in the file.
* Preconditions:
* We assume that after every punctuation mark and word delimiter there is a
* whitespace character.
* Postconditions:
* The file pointer will be positioned at the end of the stream.
*/
long CountWords(FILE* stream)
{
long counter = 0L;
char c = 0x01;
bool isInsideWord = true;
while(c!=EOF)
{
c = fgetc(stream);
if(isInsideWord==true)
{
counter++;
isInsideWord = false;
}
else if(isspace(c))
{
isInsideWord = true;
}
}
return counter;
}
We shall use the boolean variable isInsideWord in order to memorize the state of the file pointer. If a whitespace character was read, the state of isInsideWord will be toggled (will signify either the start or the end of a word).I assumed that the text is written correctly and there no construction such as "There is no space after this point.Cool!". I tested the function with various text files and it gives results close to the word counter provided by LibreOffice.
4.Example
#include <stdio.h>
#include <stdbool.h>
#include <ctype.h>
#define NR_ARGS 2
#define FILE_ARG_INDEX 1
#include<stdio.h>
long CountCharacters(FILE* stream);
long CountLines(FILE* stream);
long CountWords(FILE* stream);
/*
* Description:
* The program prints the number of characters, lines and words existing
* in a text file. It should be called like:
* Counter file.txt
*/
int main(int argc, char** argv)
{
FILE* stream = NULL;
long characters = 0UL, lines = 0UL, words = 0UL;
if(argc==NR_ARGS)
{
stream = fopen(argv[FILE_ARG_INDEX],"rt");
if(stream!=NULL)
{
characters = CountCharacters(stream);
/*The function positions the cursor at the end of the
stream. In order to count correctly the cursor should
positioned at the start of the stream*/
rewind(stream);
lines = CountLines(stream);
/*The function positions the cursor at the end of the
stream. In order to count correctly the cursor should
positioned at the start of the stream*/
rewind(stream);
words = CountWords(stream);
/*The function positions the cursor at the end of the
stream. In order to count correctly the cursor should
positioned at the start of the stream*/
rewind(stream);
printf("Characters: %ld\n"
"Lines : %ld\n"
"Words : %ld\n",
characters,lines,words);
fclose(stream);
}
else
{
perror("Could not open file");
}
}
else
{
perror("Incorrect number of arguments");
}
return 0;;
}
No comments:
Post a Comment
Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!