2016-11-24 137 views
1

我想从每行开始在poem.txt中大写其他每个单词。我做了一个函数capitalize(),它接收一个字符串(例如:“一个像根三的孤独数字”),大写其他每个单词并返回它(例如:返回“一个孤独的数字像根三”)。我试图从poem.txt读取每行,将该行发送到大写(),然后接收更新的字符串,并用更新的字符串替换该行,但我无法弄清楚如何。我测试了我的程序,它可以读取文件的内容,并将它们发送到大写()并逐行显示,但无法写入和替换每行。我尝试使用fprintf(),但它不工作。你们能开导我吗?使用C替换文本文件中的每一行C

一下poem.txt(执行前)
我担心,我会永远
一个孤独的数字,如根3
三是所有的美好和正义,
为什么一定要我三看不见
在恶性方根符号下面,
我希望改为我是一个九
九个会阻碍这个邪招,
只用一些简单的算术
我知道我永远也看不到太阳,为1.7321
这就是我的现实,一个可悲的非理性
当徐克!这是什么我看到,
的三
另一个平方根已悄然来临华尔兹通过,
在一起,现在我们乘
形成一批我们愿意,
大喜为整数
我们从我们凡人的债券中挣脱
随着魔棒的浪潮
我们的平方根s igns成为脱胶
你对我的爱已续签

代码:

#define _GNU_SOURCE 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 

int reverse(int otherWord) 
{ 
    if (otherWord) 
     return 0; 
    else 
     return 1; 
} 
void capitalise(char *s) 
{ 
    int start = 1; 
    int otherWord = 1; 
    for (; *s; s++) 
    { 
      if (start && otherWord) 
       *s = toupper(*s); 
      start = isspace(*s); 
      if (start) 
       otherWord = reverse(otherWord); 

    } 
} 
int main(int argc, char *argv[]) 
{ 
    FILE * fp; 
    char * line = NULL; 
    size_t len = 0; 
    ssize_t read; 

    fp = fopen("poem.txt", "r+"); 
    if (fp == NULL) 
     exit(EXIT_FAILURE); 

    while ((read = getline(&line, &len, fp)) != -1) { 
     capitalise(line); 
     fprintf(fp, "%s", line); // Here's the problem, this line! 

    } 

    fclose(fp); 
    if (line) 
     free(line); 
    exit(EXIT_SUCCESS); 
} 

诗。TXT(执行后):
我担心,我会永远
我担心,我会一直
EE
的Ee
三是所有的美好和正义,
3是所有这是好的和正确的,
eath恶性平方根标志,
艾比的Viciou广场根号,
NE可阻止这个邪恶的伎俩,
NE可挫败这个邪招,
知道我永远也看不到太阳,为1.7321
知道我永远不会看到太阳,作为1.7321
en hark!这是什么我看,
恩哈克!这是什么我明白了,
Ë
Ë
静静地进来华尔兹通过,
静静地来华尔兹通过,
形式的数量,我们愿意,
表格,我们更喜欢号码,
从我们的凡人债券中解脱出来
E破解我们的凡间债券
uare根号被掀开
Uare根号被掀开
EDED

一下poem.txt(预期执行):
我担心,我会一直
一个孤独的号码,例如根三
...

+0

你需要'fseek'和'ftell'。读取前用'ftell'保存位置。读线。在写之前用'fseek'设置位置并保存位置。 – BLUEPIXY

回答

2

该行因为您正在写入原始文件并同时读取它,所以发生了复制。

事实证明,从文件中删除和编辑行可能非常困难。如果要编辑文件中的行,可以使用一种简单的方法写入新的临时文件,将其重命名为原始文件,然后删除临时文件。

0

如果我没有记错的话,您应该能够重写该文件的内容,因为它已经存在标志“w”。用“w”代替你的“r +”

+1

我刚刚试过'w'。它所做的只是清空文件。 – Beginner

+0

我想我只清除了删除现有数据的第一部分,因此您可以重写 – Shazy

+0

我刚刚尝试了一个使用“w +”的示例。我创建了一个文件,然后编写了一个小程序来覆盖内容,并且它做到了。 – Shazy

2

可以做到位,但它是危险的,如果失败了,你可能会丢失数据。

稍微简化版本将

#define _GNU_SOURCE 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <ctype.h> 

int reverse(int otherWord) 
{ 
    if (otherWord) { 
    return 0; 
    } else { 
    return 1; 
    } 
} 

void capitalise(char *s) 
{ 
    int start = 1; 
    int otherWord = 1; 
    for (; *s; s++) { 
    if (start && otherWord) { 
     *s = toupper(*s); 
    } 
    start = isspace(*s); 
    if (start) { 
     otherWord = reverse(otherWord); 
    } 
    } 
} 

int main(void) 
{ 
    FILE *fp; 
    char *line = NULL; 
    size_t len = 0; 
    ssize_t read; 
    long offset = 0L; 
    int res; 
    // you might prefer "w+" instead 
    fp = fopen("poem.txt", "r+"); 
    if (fp == NULL) { 
    fprintf(stderr, "Opening file poem.txt failed\n"); 
    exit(EXIT_FAILURE); 
    } 

    while ((read = getline(&line, &len, fp)) != -1) { 
    capitalise(line); 
    // set position relative to start of file 
    if ((res = fseek(fp, offset, SEEK_SET)) < 0) { 
     fprintf(stderr, "fseek failed\n"); 
     exit(EXIT_FAILURE); 
    } 
    // printing line sets file pointer to end of line 
    fprintf(fp, "%s", line); 
    // get that position 
    offset = ftell(fp); 
    } 
    // fclose() might fail, too, see man-page for details 
    fclose(fp); 
    if (line) { 
    free(line); 
    } 
    exit(EXIT_SUCCESS); 
} 
+0

谢谢,这个作品! – Beginner