我希望创建一个C函数,在该函数中,它将根据用户输入的条目搜索文件,并能够替换那里的内容。我见过类似的c ++示例,但我不太了解c ++。任何建议或示例代码,以帮助我开始将是惊人的。我的理解是我需要打开原始文件进行读取,打开一个新文件进行写入,一次读取一行orig文件,将该行写入新文件,完成后删除原始文件,并重命名新文件文件的原始文件名。
任何带有解释的建议或示例代码都是最有帮助的
编辑经过进一步的研究,我在想是否可以找到一种方法来查找文件,搜索文件,进行更改,然后将其转换回文件就可以了更容易。
答案 0 :(得分:1)
尝试这样的事情: -
#include <stdio.h>
#include <string.h>
#define MAX_LEN_SINGLE_LINE 120 // ?
int main()
{
const char fileOrig[32] = "myOriginalFile.txt";
const char fileRepl[32] = "myReplacedFile.txt";
const char text2find[80] = "lookforme";
const char text2repl[80] = "REPLACE_WITH_THIS";
char buffer[MAX_LEN_SINGLE_LINE+2];
char *buff_ptr, *find_ptr;
FILE *fp1, *fp2;
size_t find_len = strlen(text2find);
fp1 = fopen(fileOrig,"r");
fp2 = fopen(fileRepl,"w");
while(fgets(buffer,MAX_LEN_SINGLE_LINE+2,fp1))
{
buff_ptr = buffer;
while ((find_ptr = strstr(buff_ptr,text2find)))
{
while(buff_ptr < find_ptr)
fputc((int)*buff_ptr++,fp2);
fputs(text2repl,fp2);
buff_ptr += find_len;
}
fputs(buff_ptr,fp2);
}
fclose(fp2);
fclose(fp1);
return 0;
}
答案 1 :(得分:1)
使用面向行的函数进行读写很容易,通常会使用scanf来获取用户输入。
困难的部分是进行适当的错误检查,大多数情况都会遗漏,直到为时已晚。
这是使用最佳实践的一个很好但不完美的例子。总有更好,更有效的方法,但首先要做的就是完成这项工作,并为您提供良好的C语言。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define BUFFER_SIZE 512
static void searchAndReplace(char* original_file,char* destination_file,char *searchString,char *replacementString){
FILE* original = NULL;
FILE* modified = NULL;
char origLine[BUFFER_SIZE]; //buffer, assuming the longest line will be BUFFER_SIZE -1 characters, being the null terminator the last one
size_t searchStringLength = strlen(searchString);//length without terminating NULL.
memset(origLine,0,BUFFER_SIZE);// filling with nulls just in case
original = fopen(original_file,"r");
if(!original){
printf("Error opening file for reading : %s \n",original_file);
perror("Cause of Error");
exit(2);
}
modified = fopen(destination_file,"w+");
if(!modified){
printf("Error opening file for writing: %s \n",destination_file);
perror("Cause of Error");
exit(2);
}
while(NULL != (fgets(origLine,BUFFER_SIZE,original) )){
char* searchStringPos=NULL;
/*it begins to concatenate at the beginning of the string, next position is strlen(searchString) from the last
searchString pointer position*/
char* lastConcatPos = origLine;
if(feof(original) != 0){
break;
}
while ( (searchStringPos = strstr(lastConcatPos,searchString)) != NULL ){
/* offset between position where searchStringPos was found and the last position being concantenated */
char tempBuffer[BUFFER_SIZE];
size_t sizeToConcatenate = (size_t)(searchStringPos - lastConcatPos);
/* if searchString was located at the beginning of the line or right after the last occurrence do nothing */
if(sizeToConcatenate >0){
strncpy(tempBuffer,lastConcatPos,sizeToConcatenate);
tempBuffer[sizeToConcatenate]='\0';
fputs(tempBuffer,modified);
}
fputs(replacementString, modified);
lastConcatPos = searchStringPos + searchStringLength;/* continue search after current occurrence*/
}
fputs(lastConcatPos,modified);
}
fclose(original);
fclose(modified);
}
static void askUserForInput(char* data_storage,char* text_message){
int result = 0;
do{
//printf("%s, | %s\n | result = %i",text_message,data_storage,result);
printf("%s\n",text_message);
fflush(stdout);
result = scanf("%s",data_storage);
}while(result ==0 );
}
int main(int argc,char* argv[]){
/* Use: program <original_filename> <modified_filename> <string_to_search> <replacement_string> or
* program for asking the user for input */
if(argc == 5){
searchAndReplace(argv[1],argv[2],argv[3],argv[4]);
}else if(argc == 1){
char origin_file[128];
char destination_file[128];
char search_string[128];
char replacement_string[128];
askUserForInput(origin_file,"Enter origin file please");
askUserForInput(destination_file,"Enter destination file please");
askUserForInput(search_string,"Enter search string please");
askUserForInput(replacement_string,"Enter replacement string please");
searchAndReplace(origin_file,destination_file,search_string,replacement_string);
}else{
printf("Usage:\n %s <original_filename> <modified_filename> <string_to_search> <replacement_string>\n or"
"%s without parameter for asking for input",argv[0],argv[0]);
exit(1);
}
return 0;
}
编辑:还有很大的改进空间,比如检查每个函数中的NULL指针,更改searchAndReplace
以在成功时返回int
= 0,其他根据错误类型返回调用者管理其余的程序行为,如再次尝试而不是退出程序等。
错误处理部分的printf
也应该替换为fprintf(stderr,"message",..)
这是一些可以用来改进和学习的想法和概念。希望你有很多乐趣
答案 2 :(得分:0)
使用仅识别文字的愚蠢语法创建lex-scanner的一个很好的解决方法。在下面的例子中,“aaaa”被“AAAA”等替代。输出未重新扫描。
%%
"aaaa" { fputs("AAAA", stdout ); }
"bbbb" { fputs("BBBB", stdout ); }
"cccc" { fputs("CCCC", stdout ); }
. { ECHO; }
[ \t\r\n]+ { ECHO; }
%%
这个的makefile片段:
#Makefile
LDFLAGS := -lfl
###################
replace: replace.o
$(CC) -o $@ $? $(LDFLAGS)
replace.o: replace.c
replace.c: replace.l
(但是使用sed可能会更容易) 这种方法的一个很好的特性是(f)lex完成所有缓冲,并且只需要最少量的缓冲。由于lex创建了DFA,因此该方法也很快:有效地,所有字符串并行匹配。