使用 FILE* 和结构数组在 C 中实现责任链
Implementing chain of responisiblity in C with FILE* and array of structs
我的目标是创建一个从 CMD 直接写入文本文件的程序。
如果输入字符串是以下字符串之一:
-exit
-count
-remove
它将执行退出程序/计算文件中的行/删除文件的任务。
我编写的代码在我的脑海中基本上看起来“不错”,但在纸上(在显示器上)却很糟糕。
main function
100% 有效(没有调用 InputCmp function
。
我不明白为什么我不能真正将这些结构相互连接起来。
我想创建一个按以下方式工作的责任链:
假设用户写入字符串:"-exit"
,但退出是 3 结构(数组中的索引 2)。
所以我希望将字符串发送到一个函数(我编写的函数称为 InputCmp
),该函数将检查 strcmp
与第一个结构内的字符串,即 -remove
.
如果不匹配,它将与数组中的下一个结构进行比较。
直到它找到其中包含确切字符串的第三个结构,然后它将 运行 一个退出函数。
但是,这里的主要问题是以某种方式将 FILE*
从一个函数转移到另一个函数。我的意思是我需要将它从 main
转移到 InputCmp
并从 InputCmp
转移到每个函数,因为 count
和 remove
需要文件才能操作。
我刚刚迷路了。
#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;
}
不幸的是你cannot derive the filename from the FILE object。
要解决这个问题,您首先必须移动这些:
handlers[0].RunTask = RemoveFile;
handlers[1].RunTask = CountLines;
handlers[2].RunTask = ExitProgram;
在主函数中,修正函数中的小错误(比如\n不是n,\n允许行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);
}
在您的主函数中,您调用的函数如下:
handlers[0].RunTask("file.txt");
handlers[1].RunTask("file.txt");
handlers[2].RunTask("file.txt");
或:
CountLines("file.txt");
RemoveFile("file.txt");
ExitProgram("");
我的目标是创建一个从 CMD 直接写入文本文件的程序。
如果输入字符串是以下字符串之一:
-exit
-count
-remove
它将执行退出程序/计算文件中的行/删除文件的任务。
我编写的代码在我的脑海中基本上看起来“不错”,但在纸上(在显示器上)却很糟糕。
main function
100% 有效(没有调用 InputCmp function
。
我不明白为什么我不能真正将这些结构相互连接起来。
我想创建一个按以下方式工作的责任链:
假设用户写入字符串:"-exit"
,但退出是 3 结构(数组中的索引 2)。
所以我希望将字符串发送到一个函数(我编写的函数称为 InputCmp
),该函数将检查 strcmp
与第一个结构内的字符串,即 -remove
.
如果不匹配,它将与数组中的下一个结构进行比较。
直到它找到其中包含确切字符串的第三个结构,然后它将 运行 一个退出函数。
但是,这里的主要问题是以某种方式将 FILE*
从一个函数转移到另一个函数。我的意思是我需要将它从 main
转移到 InputCmp
并从 InputCmp
转移到每个函数,因为 count
和 remove
需要文件才能操作。
我刚刚迷路了。
#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;
}
不幸的是你cannot derive the filename from the FILE object。
要解决这个问题,您首先必须移动这些:
handlers[0].RunTask = RemoveFile;
handlers[1].RunTask = CountLines;
handlers[2].RunTask = ExitProgram;
在主函数中,修正函数中的小错误(比如\n不是n,\n允许行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);
}
在您的主函数中,您调用的函数如下:
handlers[0].RunTask("file.txt");
handlers[1].RunTask("file.txt");
handlers[2].RunTask("file.txt");
或:
CountLines("file.txt");
RemoveFile("file.txt");
ExitProgram("");