程序应该从stdin
读取数据到文本文件,然后对文件执行查找和替换,条件是新单词比旧单词长。它编译没有任何错误或警告罚款,但问题是fread
不起作用,它似乎返回0所以while循环不起作用。打印文件功能就是可以检查文件的内容,它不是最终代码的一部分。
#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);
}
}
代码不完整,只缺少一小段,我不会将修改后的版本移回原始文件。
为什么fread
返回零?代码中是否还有其他错误?
我意识到我应该在最后释放缓冲区。
答案 0 :(得分:1)
您想将第二个和第三个参数交换为fread()
。
你拥有它的方式,如果它可以读取1
个字节,它将只返回BUFFER_SIZE
。
n = fread(buffer, 1, BUFFER_SIZE, original_file);
if (n == BUFFER_SIZE) /* buffer full, needs to read more */;
if (n > 0) /* read n bytes */;
评论中建议的更好的方法是使用fgets()
。
答案 1 :(得分:0)
你不应该在那里使用&buffer
。由于缓冲区已经是一个char指针,因此将buffer
作为fread和fwrite的第一个参数传递。