I'm using the following code to print last N
lines of one file to the other.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void printLastNLines(const std::string& inputFileName, const std::string& outputFileName, int N);
int main()
{
printLastNLines("test.csv", "test2.csv", 200);
}
void printLastNLines(const std::string& inputFileName, const std::string& outputFileName, int N) {
FILE* in, * out;
int count = 0;
long int pos;
char s[100];
fopen_s(&in, inputFileName.c_str(), "rb");
/* always check return of fopen */
if (in == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
fopen_s(&out, outputFileName.c_str(), "wb");
if (out == NULL) {
perror("fopen");
exit(EXIT_FAILURE);
}
fseek(in, 0, SEEK_END);
pos = ftell(in);
while (pos) {
pos--;
fseek(in, pos, SEEK_SET);
char c = fgetc(in);
if (c == '\n') {
if (count++ == N) break;
}
}
//fseek(in, pos, SEEK_SET);
/* Write line by line, is faster than fputc for each char */
while (fgets(s, sizeof(s), in) != NULL) {
fprintf(out, "%s", s);
}
fclose(in);
fclose(out);
}
The contents of the sample file test.csv
is given below:
2
3
However, when I run the code, test2.csv
contains the following (not that the first line is there but doesn't contain any character:
3
Can anyone guide what's wrong with the code? In general, when I give it even a bigger file, the first character of the first line is always missing.
I assumed it has something to do with the file pointer position. So, I used another fseek(in, pos, SEEK_SET);
(currently commented out) and the first line with 2
started printing. However, I'm not sure why does it need this extra fseek
. When I debugged the code, the last line executed is in fact fseek(in, 0, SEEK_SET);
. Why do we need an extra fseek(in, 0, SEEK_SET);
to make it work?