Чтение и запись с помощью линейно-ориентированных функций очень просты, для получения пользовательского ввода часто используется 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",..)
Это некоторые идеи и концепции, которые вы можете использовать для улучшения и изучения гораздо большего.Надеюсь, вам будет весело