Well, I have a text file containing some lines. When I have to "delete" a line (known position from the start of the file) I read as many lines as needed until I reach the desired position; then from that position, I start to overwrite with the remaining lines after the line to be "deleted", now the old line is deleted.
But my idea is to move the EOF to the old last line, which needs to be deleted as it's now a duplicate. How I print or move the EOF (End Of File)?
Related
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.
I have a file in which on each line there are multiple sentences separated by white spaces. SOmetimes one sentence may extend to next line. I want to extract these sentences separated by white space. My code successfully extracts sentences on same line separated by white space but since it is reading line by line. SO, issue comes when one sentence is extended to next line.
Store the part unused in creation of line at each iteration in temperary buffer. Include the buffer in the next iteration (append at the begining of line read).
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.)
My goal is to print out every full line from a text file if that line contains a string that is equivalent to user input.
I understand how to find the occurrences of a specific string in a text file, but I am confused as to how to associate that with a specific line. How do I relate my string with the specific line that it is in?
My initial thought was to store each line in an array and then print out that line if the user string is somewhere in that line.
However each line is a different size, so I was wondering if it is possible for me to initially divide my entire text file into x number of lines and then use a loop to go through each line and search for that string?
Save the file pointer of the starting of the line in a temp variable before starting new line compare
I am reading a file with fgetc, so each time it reads a character, the cursor positio gets changed.
Is it possible to know, after each read, the "coordinates" of the cursor on the file in terms of column and line number?
Thanks
You can use ftell
It does not give you the position in terms of row and column but gives the current position in the stream from the start.
There is no "coordinates" in a file, only a position. A text file is simply a stream of bytes, and lines are separated by line breaks. So, when reading a text file you can calculate your "coordinates" if you scan the whole file. This means, if you really need some "row" and "column" value:
Read the file line by line. Count the newline characters, and you get the "row" number. Be aware that there are different line break characters on different OS -- unix line endings are different to Windows.
Read the line in question character by character and count the characters to the position in question. This will get you the "column" number. You obviously need to accept that the number of "columns" can vary between "rows", and it's perfectly possible to have "rows" with a "column count" of 0.
A different approach would be to
Read the file line by line and build an array of the position (using ftell) of the line breaks.
Now to figure the position of any character just get its position in the file, then find the nearest previous line break. From the line break count up to the character you get the "row", from the difference between the line break position and the current position you get the "column".
But most important is to accept that there is no rows or columns in files -- there's a position in a file, but the file itself is simply a stream of bytes. This also means that you would need to handle files encoded with wide character sets differently, as a character doesn't map to a byte anymore.