我应该编写一个程序,它接受一个文本文件(包含纯文本)并纠正以下错误(涉及标点符号):
Hello , there! --> Hello, there!
Hello ,there! --> Hello, there!
A sentence. this should be capitalized --> A sentence. This should be capitalized
我提出的算法如下: 我逐行循环遍历文本文件,并将每一行传递给错误查找器功能。此函数检测上述(第1和第2)错误,并在错误数组中存储双数。整数部分显示错误开始的位置,小数部分显示错误的类型。
例如,如果我将"Hello , there!"
作为参数传递,则存储在数组中的双精度数为5.1,因为错误从字符串的第5个字符开始,为0.1,因为它是第1种错误。< / p>
类似地"Hello ,there!"
将在数组中存储5.2(第二类错误)。
找到错误后,一段代码会将新的更正行写入不同的文件中。
FILE *src, *dst; //source file, destination file
int ptr; //shows how many mistakes were found in the line
src = fopen((const char*)filename, "r"); //opening both files
dst = fopen("temp.txt", "w");
char array[1024];
double mistakes[1024];
double mistakeType, position;
int i, j, pos = 0, capitalNeeded = 1; //capitalNeeded shows whether the next letter should be capitalized
while(fgets(array, 1024, src)!=NULL){ //taking the content of the file line by line
puts(array);
ptr = findMistakes(array, mistakes); //the mistakes of the current line are located, and their types are defined
for(i=0; i<ptr; i++){ //looping through the mistakes
if(capitalNeeded && isalpha(array[pos])){
array[pos] = toupper(array[pos]);
capitalNeeded = 0;
}
mistakeType = modf(mistakes[i], &position); //position will be of type int.0000..
for(j=pos; j<position; j++){
if(array[j] == '.' || array[j] == '?' ||array[j] == '!'){ //testing if a capital letter is needed
capitalNeeded = 1;
}
if(capitalNeeded && isalpha(array[j])){
array[j] = toupper(array[j]);
capitalNeeded = 0;
}
}
pos = j+1; //pos becomes the last j+1, basically shows the next character to be read from the array
if(mistakeType == 0.1){ //if mistake was of type 1
//then pos points to a space character ' '. The space is bypassed and the next
//character is placed in the file
fprintf(dst, "%c", array[pos+1]); //which is a punctuation character
fprintf(dst, "%c", array[pos+2]); //then a space is placed
pos += 3; //the next character to be read and placed becomes pos+3
}
else{ //only 2 type of mistakes exist, so if it's not of type 1 then it's of type 2
//In a type 2 mistake the punctuation mark is attached to the next letter
//pos currently points to a space character ' ', and pos+1 to a punctuation mark.
fprintf(dst, "%c", array[pos+1]);
fprintf(dst, "%c", array[pos]);
pos += 2; //the next character to be read and placed becomes pos+2
}
}
fprintf(dst, "%c", '\n'); //the line is changed
pos = 0; //pos is reset, and readied for the processing of the next line
}
但是,我无法判断我的算法是否有效,因为fputc
不起作用。编译中没有错误,但新文件为空。我理解fputc()
需要int
个参数,所以我尝试使用fprintf(dst, "%c", array[...]);
,但这产生了完全相同的结果。我搜索但找不到答案,感谢任何帮助......
答案 0 :(得分:1)
Valgrind有关您的代码的错误。
==20508== Use of uninitialised value of size 8
==20508== at 0x4EA7A9E: fgets (iofgets.c:47)
==20508== by 0x400D0E: main (in /home/dac/ClionProjects/replace/a.out)
==20508==
==20508== Invalid read of size 4
==20508== at 0x4EA7A9E: fgets (iofgets.c:47)
==20508== by 0x400D0E: main (in /home/dac/ClionProjects/replace/a.out)
==20508== Address 0x0 is not stack'd, malloc'd or (recently) free'd
我建议你使用字符串替换。我希望这个例子可以帮到你。
<强> TEMP.TXT 强>
您好,有!你好!一句话。这应该是大写的
(我们将把空格作为字符串操作并将其写入文件file.txt)
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
// You must free the result if result is non-NULL.
char *str_replace(char *orig, char *rep, char *with) {
char *result; // the return string
char *ins; // the next insert point
char *tmp; // varies
int len_rep; // length of rep
int len_with; // length of with
int len_front; // distance between rep and end of last rep
int count; // number of replacements
if (!orig)
return NULL;
if (!rep)
rep = "";
len_rep = strlen(rep);
if (!with)
with = "";
len_with = strlen(with);
ins = orig;
for (count = 0; tmp = strstr(ins, rep); ++count) {
ins = tmp + len_rep;
}
// first time through the loop, all the variable are set correctly
// from here on,
// tmp points to the end of the result string
// ins points to the next occurrence of rep in orig
// orig points to the remainder of orig after "end of rep"
tmp = result = malloc(strlen(orig) + (len_with - len_rep) * count + 1);
if (!result)
return NULL;
while (count--) {
ins = strstr(orig, rep);
len_front = ins - orig;
tmp = strncpy(tmp, orig, len_front) + len_front;
tmp = strcpy(tmp, with) + len_with;
orig += len_front + len_rep; // move to next "end of rep"
}
strcpy(tmp, orig);
return result;
}
char * Cap(char *string) {
int i;
int x = strlen(string); // You want to get the length of the whole string.
for (i=2;i<x;i++){
if (isalpha(string[i]) && string[i-1] == ' ' && string[i-2] == '.'){
// only first letters of a word.
string[i]= toupper(string[i]);
}
}
return string;
}
void adx_store_data(const char *filepath, const char *data)
{
FILE *fp = fopen(filepath, "ab");
if (fp != NULL)
{
fputs(data, fp);
fclose(fp);
}
}
int main(void)
{
FILE * fp;
char * line = NULL;
size_t len = 0;
ssize_t read;
// char *s = str_replace("aaabaa", 'b', "ccccc");
// printf("%s\n", s);
// free(s);
fp = fopen("/home/dac/ClionProjects/replace/temp.txt", "r");
if (fp == NULL)
exit(EXIT_FAILURE);
while ((read = getline(&line, &len, fp)) != -1) {
printf("Retrieved line of length %zu :\n", read);
printf("%s\n", line);
str_replace(line, "e", ",");
line = str_replace(line, " ,", ",");
line = str_replace(line, ",", ", ");
line = str_replace(line, " ", " ");
printf("Output: %s", Cap(line));
line = Cap(line);
}
FILE *f = fopen("file.txt", "w");
if (f == NULL)
{
printf("Error opening file!\n");
exit(1);
}
/* print some text */
// const char *text = "Write this to the file";
fprintf(f, "%s\n", line);
fclose(f);
fclose(fp);
if (line)
free(line);
exit(EXIT_SUCCESS);
}
测试它:
Retrieved line of length 67 :
Hello , there! Hello ,there! A sentence. this should be capitalized
Output: Hello, there! Hello, there! A sentence. This should be capitalized