The program is supposed to read data from stdin to a text file, and then perform a find and replace on the file, with the condition that the new word is longer than the old one. It compiles fine without any errors or warnings, but the issue is that fread is not working, it seems to return a 0 so the while loop isn't starting. The print file function is just there to be able to check the contents of the file, it's not part of the final code.
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUFFER_SIZE 1000 #define OLD_WORD_SIZE 24 #define NEW_WORD_SIZE 64 void write_to_file(const char *s); void replace_word(const char *s, const char *old, const char *new); void print_file(const char *s); int main(void){ const char file_name[] = "text.txt"; int c; char old_word[OLD_WORD_SIZE]; char new_word[NEW_WORD_SIZE]; while((c = getchar()) != EOF){ switch(c){ case 'w': getchar(); write_to_file(file_name); break; case 'r': getchar(); puts("Enter the word you want to replace"); fgets(old_word, sizeof(old_word), stdin); old_word[strlen(old_word) - 1] = '\0'; puts("Enter the new word"); fgets(new_word, sizeof(new_word), stdin); new_word[strlen(new_word) - 1] = '\0'; if(strlen(old_word) >= strlen(new_word)){ printf("Error: can't replace \"%s\" with \"%s\":\n\"%s\" is too small\n", old_word, new_word, new_word); break; } replace_word(file_name, old_word, new_word); getchar(); break; case 'p': print_file(file_name); getchar(); getchar(); break; default: printf("Invalid command:%i\n", c); break; } } return 0; } void write_to_file(const char *s){ FILE *out_file; if((out_file = fopen(s, "w")) == NULL){ perror(s); exit(EXIT_FAILURE); } int c; while((c = getchar()) != EOF){ fputc(c, out_file); } fclose(out_file); } void print_file(const char *s){ FILE *in_file; if((in_file = fopen(s, "r")) == NULL){ perror(s); exit(EXIT_FAILURE); } int c; while((c = fgetc(in_file)) != EOF){ printf("%c", c); } fclose(in_file); } void replace_word(const char *s, const char *old_word, const char *new_word){ char *buffer = malloc(BUFFER_SIZE); FILE *original_file; FILE *copy; if((original_file = fopen(s, "r")) == NULL){ perror(s); exit(EXIT_FAILURE); } if((copy = fopen("copy.txt", "w")) == NULL){ perror("text"); exit(EXIT_FAILURE); } int old_word_len = strlen(old_word); int new_word_len = strlen(new_word); char *src; char *dst; char *tmp; while(fread(&buffer, BUFFER_SIZE, 1, original_file) == 1){ if((tmp = strstr(buffer, old_word))){ buffer = realloc(buffer, BUFFER_SIZE + new_word_len - old_word_len + 1); src = tmp + old_word_len; dst = tmp + new_word_len; memmove(dst, src, BUFFER_SIZE - strlen(src)); memcpy(tmp, new_word, new_word_len); fwrite(&buffer, BUFFER_SIZE + new_word_len - old_word_len + 1, 1, copy); } else{ fwrite(&buffer, BUFFER_SIZE, 1, copy); } fseek(original_file, -old_word_len, SEEK_CUR); } } The code is incomplete, it's only missing a small segment, I don't move the modified version back to the original file.
Why is fread returning a zero? Are there any other mistakes in the code?
I realise I should free buffer at the end.
freadon a text file. Read line by line withfgets. Otherwise thefreadmight break a word you want to detect.fgetswouldn't work here because it'll stop on the first '\n`. I need to read a specific number of bytes.fread(buffer, 1, BUFFER_SIZE, original_file), i.e. read (at most) BUFFER_SIZE items of size 1."fi\nnd"fseek(original_file, -9, SEEK_CUR);? What is that supposed to do?