Jump to end of specific line - c

I am trying to change my cursor position in an opened file.
fp = fopen("dirty", "a+");
fprintf(fp, "Text at end of file");
// seek to end of third line (eg.)
fprintf(fp, "Text at end of third line");
I have tried closing and reopening the file, and fseek, which didn't work.
Any help would be greatly appreciated.

To find a position in a file, use fseek(). There is no knowledge in C/C++ file handling to know about where lines start and/or end, other than in the sense that there are "end of line markers", newline ('\n').
To know where a line starts or ends you have to track that yourself (e.g. by reading the file character by character with fgetc(), element by element with fscanf() or line by line fgets() and when you find certain important parts, use ftell() to save the current position.
Note that whilst it may appear that fgets() knows about lines, it really just reads from where you are in the file, and when the character is a newline, it stops. But there's no knowledge available about "this line is 40 characters long".

You'll have to fseek to the beginning of the file, then read char by char with getc until you found the third newline, then ungetc (which can only unget exactly one character). Note however that you cannot insert text after the third line without overwriting the fourth.
(Inserting in the middle of a file is usually performed by copying the initial part, writing the new data, and then copying the final part.)

Related

Why does adding a \n character while appending make it possible to print out the last appended line?

I am trying to write some C code that appends a line of text to a file, and then simply display it line by line. When I open the file in append mode and add a line using fprintf, the line gets added and I can see it when I open the file with a text editor. However when I call a function to display all lines (which works fine before the new text is appended), I get all the lines until the last but excluding the new appended line.
Here is the code I'm working with. The first function just adds a new line, and the second function just reads all the lines. The read_csv() works initially when I haven't appended any lines through code and have just used a text editor to add my initial lines.
void add_record(const char* csv_filename)
{
FILE *f = fopen(csv_filename,"at");
char str="My appended line "
fprintf(f,"%s",str);
fclose(f);
}
void read_csv(const char* csv_filename)
{
FILE *f = fopen(csv_filename,"rt");
char str[MAX];
fgets(str,MAX,f);
while(!feof(f))
{ fputs(str,stdout);
fputs("\n",stdout);
fgets(str,MAX,f);
}
fclose(f);
}
Now I found two fixes to my problem but I don't exactly understand why they work.
Fix 1 : Adding an extra fgets() prints the missing appending line when I'm trying to display it, however when I use it to display my original text file it prints the last line twice..so not a good fix.
fgets(str,MAX,f)
while(!feof(f))
{ fputs(str,stdout);
fputs("\n",stdout);
fgets(str,MAX,f);
}
fgets(str,MAX,f)
Fix 2 : Adding a new line character at the along with the string appended fixes the problem perfectly and everything is smooth. All the lines get displayed when I call read_csv().
char str="My appended line "
fprintf(f,"%s\n",str)
Looking at the docs for fgets(), it says it reads until either a new line character or eof has reached(whichever occurs first), so I don't understand why my appended line get ignored by fgets().
When fgets() reaches the last line(which it skips) the situation I presume is something like this: it gets a string with " text text text eof",and it breaks out the loop skipping the print statement. But then when I use an extra fgets() outside the while loop it works. Also when I add a new line and the situation is a string like " text text text \n eof", it doesn't quit the loop and goes on to display it.
I would really appreciate if I could get some info on what is happening and why these two fixes work. I suspect it is something to do with the feof detecting an eof or some specifics about fgets but I couldn't find anything satisfactory online.
Thank you so much in advance for taking the time to read and respond.

why is fgetc or fgets ignoring

Today I almost became crazy because the size of the bytes I read didn't match the size of the xml file I was trying to read.
Then, when I checked the content of the file I was reading, I said it must be a nasty non printable char (\r) and I checked that with a simple program : the \r were not present.
My question is why fgetc/fgets are ignoring \r and picking only \n and If I want \r to be read how can I proceed ?
Because they are designed to do so. On the Windows OS the end of line is a combination of two characters '\n' (new line) and '\r' (carriage return).
When you open a file with the "r" mode these are all converted to '\n' so if you are in a Windows OS there will be one character missing from each line.
If you open with the "rb" mode, it will no longer convert the two characters to '\n' and you will be able to read it. This is the primary difference between the "b" and non "b" modes.
Note that this freature allows the file to be open by different platforms without caring about this at all, you simply open it in text mode "r" or "w" for output and don't worry about the way the underlying system represents end of lines.

Using scanf to re-read a text file in c

I am currently writing a program in c that requires me to read a text file more than once. That is, I am reading the data from the first line of the text file (which is fine), but then want to go back and re-read the same data from the same first line of the text file again (my problem). The data on the text file are simple numbers spaced out such that they may be read with scanf. I am a beginner and would appreciate some help. If it is in fact not possible to do this using scanf what can I do in order to solve my problem?
you can use rewind(FILE *stream) it is equivalent to:
fseek(stream, 0, SEEK_SET)
which sets the file position indicator for the stream pointed to by stream to the beginning of the file

error reading text file; lines read twice and with every other having extra line break

I'm reading a text file (written on a UNIX or Linux machine) that is supposed to have one entry on each line. When I read it with my program and output the file contents to the console every other entry has an extra line break and each line is repeated twice. Here is the code
FILE* fullList;
char sline[21];
fullList = fopen("fullList", "r");
if(fullList == NULL)
exit(EXIT_FAILURE);
while(fgets(sline, sizeof(sline), fullList) != NULL)
{
puts(sline);
printf(sline);
}
fclose(fullList);
So if the input file contains
apple
banana
orange
zucchini
cucumber
eggplant
the program would display it as
apple
apple
banana
banana
orange
orange
zucchini
zucchini
cucumber
cucumber
eggplant
eggplant
I'm not sure what's doing it. Must I some how clear sline before using it again?
That's because you print each line twice - once through puts, and once through printf.
fgets captures newline \n, and puts appends a '\n' of its own, so there's an additional line break after the first printout.
The last line in the file ("eggplant") lacks the trailing '\n', so there's no extra blank line in between the two eggplant printouts.
To fix this problem, first stop calling one of the printing functions. Next, make sure that the line you read does not have a \n at the end. You could either strip it off yourself, or use
while (fscanf(fulllist, "%20s", sline) == 1) {
...
}
It is not advisable to call printf with your string in the spot of the formal parameter, because having unexpected format symbols there may lead to undefined behavior. If you decide to use printf, use it as follows:
printf("%s\n", sline);
What do you think this does?
puts(sline);
printf(sline);
The first one prints the line (followed by a newline!). The second one prints the line, but formats anything starting with % in a special way. So puts() gives you an extra newline, but printf() is even worse--look up the documentation and think about what would happen if your file contains "%s" or "%d".
So you want to use only a single output statement, and you don't want double newlines. You could remove the newline from each line before printing, but even better is to use fputs(sline, stdout) which does not add a newline.
As an aside, a bit of advice: using C to process text files is going to be pretty painful for you (as a newcomer to C). I suggest using some other language, such as Python, Ruby, awk, sed, or anything else based on your needs and experience.

remove newline characters from text file while writing data

I am getting a newline character into a text file while I was writing some content into the text file using the code below
sprintf(str,"GodownName,LorryNumber,InvoiceNumber,CementCompanyName,RcvdPrsnName,RcvdPrsNDsgnation,EntityQty,Date\0");
write(fd,str,strlen(str));
the text is writing from 2nd row and an unwanted newline is writing at 1st row. I want my text to be written from 1st row. So please any one help me to remove newline characters or spaces from text file
Thanks in advance
My guess is that you have another function which writes in fd before the call of this function.
Besides, writing "\0" at the end of a string litteral is useless, there's already one.
You do not need the \0 at the end. Is str long enough? If not that could cause the problem that you are encountering.

Resources