Reputation: 105
I want to capitalise every other word in poem.txt, starting from each line. I made a function capitalise() that receives a string (eg: "a lonely number like root three"), capitalises every other word and returns it (eg: returns "A lonely Number like Root three" ). I'm trying to read each line from poem.txt, send that line to capitalise() and then receive the updated string and replace that line with the updated string but I can't figure out how. I tested my program, it can read the contents of the file and send them to capitalise() and display line by line but it can't write and replace each line. I tried using fprintf() but it's not working. Can you guys enlighten me?
poem.txt(before execution)
i fear that I will always be
a lonely number like root three
the three is all that’s good and right,
why must my three keep out of sight
beneath the vicious square root sign,
I wish instead I were a nine
for nine could thwart this evil trick,
with just some quick arithmetic
i know I’ll never see the sun, as 1.7321
such is my reality, a sad irrationality
when hark! What is this I see,
another square root of a three
has quietly come waltzing by,
together now we multiply
to form a number we prefer,
rejoicing as an integer
we break free from our mortal bonds
with the wave of magic wands
our square root signs become unglued
your love for me has been renewed
Code:
#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);
}
poem.txt (after execution):
i fear that I will always be
I fear That I Will always Be
ee
Ee
three is all that’s good and right,
three Is all That’s good And right,
eath the vicious square root sign,
Eath the Vicious square Root sign,
ne could thwart this evil trick,
Ne could Thwart this Evil trick,
know I’ll never see the sun, as 1.7321
know I’ll never See the Sun, as 1.7321
en hark! What is this I see,
En hark! What is This I See,
e
E
s quietly come waltzing by,
S quietly Come waltzing By,
form a number we prefer,
Form a Number we Prefer,
e break free from our mortal bonds
E break Free from Our mortal Bonds
uare root signs become unglued
Uare root Signs become Unglued
edEd
poem.txt(expected execution):
I fear That I Will always Be
A lonely Number like Root three
...
Upvotes: 0
Views: 87
Reputation: 1673
The line duplication happens because you are writing to the original file while also reading it.
It turns out that deleting and editing lines from a file can be quite difficult. If you want to edit lines in a file, one easy solution is to write to a new temporary file, rename it to the original file, and delete the temporary file.
Upvotes: 2
Reputation: 5525
You can do it it in-place, but it is dangerous, you might loose data if something fails.
A slightly simplified version would be
#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);
}
Upvotes: 2
Reputation:
if I remember correctly, you should be able to rewrite the content for the file since it already exist with the flag "w". Replace your "r+" with "w"
Upvotes: 0