My goal is to create a program that writes from the CMD straight to a text file.
If the input string is one of the following strings:
-exit
-count
-remove
It will do the tasks of exiting the program / counting lines in the file / removing the file.
I wrote a code that basically looks "ok"ish in my head, but on paper (on the monitor) it sucks.
The main function
works 100% (without the call for InputCmp function
.
I can't figure out why I can't really connect these structs one to each other.
I want to create a chain of responsibility that will work in the following way:
lets say the user writes the string: "-exit"
, but exit is the 3 struct (index 2 in the array).
So I want the string to be sent to a function (that I wrote called InputCmp
) that will check strcmp
with the string that inside the first struct, which is -remove
.
If it does not match, it will compare with the next struct in the array.
Till it finds the 3rd struct which has the exact string inside of it, and then it will run a function of exiting.
But, the major issue here is to transfer somehow the FILE*
from function to function. I mean I need it to be transferred from main
to InputCmp
and from InputCmp
to each of the functions because count
and remove
need the file in order to operate.
I just got lost.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define BUFF_SIZE 1024
/******************************************************/
struct processor
{
char *task;
void (*InputCmp)(char*, size_t);
void (*RunTask)(char*);
};
struct processor handlers[3];
handlers[0].task = "-remove";
handlers[1].task = "-count";
handlers[2].task = "-exit";
handlers[0].RunTask = RemoveFile;
handlers[1].RunTask = CountLines;
handlers[2].RunTask = ExitProgram;
/******************************************************/
int RemoveFile(char *string) /* needs somehow to get filename */
{
if (remove(filename) == 0)
printf("Deleted successfully");
else
printf("Unable to delete the file");
return 0;
}
/******************************************************/
void CountLines(char *string) /* needs somehow to get filename */
{
FILE *fileptr;
int count_lines = 0;
char chr;
fileptr = fopen(filename, "r");
chr = getc(fileptr);
while (chr != EOF)
{
if (chr == 'n')
{
count_lines = count_lines + 1;
}
chr = getc(fileptr);
}
fclose(fileptr); //close file.
printf("Lines: %d",count_lines);
}
/******************************************************/
void ExitProgram(char *string)
{
exit(1);
}
/******************************************************/
int InputCmp(char *string, size_t index)
{
assert(string);
if (0 == strcmp(string, handlers[index].task))
{
return handlers[index].RunTask(string);
}
return handlers[index+1].InputCmp(string,index+1);
}
/******************************************************/
int is_file_exists(char *file_name)
{
FILE *file;
if ((file = fopen(file_name,"r"))!=NULL)
{
/* file exists */
fclose(file);
return 1;
}
else
{
/*File not found, no memory leak since 'file' == NULL
fclose(file) would cause an error */
return 0;
}
}
/******************************************************/
int main(int argc, char **argv)
{
char c;
FILE *file;
char buffer[BUFF_SIZE];
if (argc >= 2)
{
if (is_file_exists(argv[1]))
{
file = fopen(argv[1], "a");
}
else
{
return 0;
}
}
else
{
file = fopen("file.txt", "a");
}
while(1)
{
size_t i = 0;
memset(buffer, 0, BUFF_SIZE);
while ((c = getchar()) != '\n' && i < BUFF_SIZE)
buffer[i++] = c;
InputCmp(buffer, 0);
buffer[i] = '\n';
fputs(buffer, file);
}
fclose(file);
return 0;
}
Unfortunately you cannot derive the filename from the FILE object.
To solve this you first have to move these:
handlers[0].RunTask = RemoveFile;
handlers[1].RunTask = CountLines;
handlers[2].RunTask = ExitProgram;
in the main function, and correct the tiny mistakes here and there in your function (like \n is not n, \n allow the line return):
int RemoveFile(char *filename)
{
if (remove(filename) == 0)
printf("Deleted successfully\n");
else
printf("Unable to delete the file\n");
return 0;
}
void (*RunTask)(char*, void*);
/******************************************************/
void CountLines(char *filename)
{
FILE *file = fopen(filename, "r");
int count_lines = 0;
char chr;
chr = getc(file);
while (chr != EOF)
{
if (chr == '\n')
{
count_lines = count_lines + 1;
}
chr = getc(file);
}
fclose(file); //close file.
printf("Lines: %d\n",count_lines);
}
/******************************************************/
void ExitProgram(char *s)
{
(void)s; // to allow compilation with -Wall -Werror
exit(EXIT_SUCCESS);
}
in your main you call functions like:
handlers[0].RunTask("file.txt");
handlers[1].RunTask("file.txt");
handlers[2].RunTask("file.txt");
or:
CountLines("file.txt");
RemoveFile("file.txt");
ExitProgram("");