04.06.2017, 22:19
Okay, I wrote a function just for you to do it. There might be better ways and there is one issue - it ignores \r for now (\n will be kept). \n\r would result in two new lines.
It creates another file with the reverse line order.
You can replace the second function with what you actually want to do - whenever buf[] is written a new line is added, but note that buf is still reversed at that point. Otherwise open the newly created file (inefficient though).
It supports as many lines as you want, however there is a maximum line length (define MAX_LINE_LENGTH).
I guess it could be improved (especially the buffer part..) but it will work.
Made this in a few minutes so if there are issues tell me (tests worked well).
Example usage:
I would suggest you try to directly implement it where you want to use it instead of creating a temporary file. That will speed things up especially for long files.
It creates another file with the reverse line order.
You can replace the second function with what you actually want to do - whenever buf[] is written a new line is added, but note that buf is still reversed at that point. Otherwise open the newly created file (inefficient though).
It supports as many lines as you want, however there is a maximum line length (define MAX_LINE_LENGTH).
PHP код:
File_LReverse(const fnamein[], const fnameout[])
{
// Open the files
new File:FIn = fopen(fnamein, io_read);
if(!FIn) return 0;
new File:FOut = fopen(fnameout, io_write);
if(!FOut)
{
fclose(FIn);
return 0;
}
new c, i = -1, j, buf[MAX_LINE_LENGTH], bool:newline; // c is the current character, i is the position (end - i), buf the temporary buffer and newline determines whether or not there was a new line at the very end (now start) of the file
do
{
fseek(FIn, i --, seek_end); // seek to end - i
c = fgetchar(FIn, 0, false); // Get character
if(c == '\r') continue;
if(c != EOF)
{
if(c != '\n') // Add to buffer
{
buf[j ++] = c;
}
else // New line - write buffer
{
if(i == -1) newline = true; // First character was a newline - keep that in mind
if(j != 0) // Buffer not empty - write
{
File_WReverse(FOut, buf, j);
fputchar(FOut, '\n', false);
j = 0;
}
}
}
else if(j != 0) // This writes the buffer because no more input is coming
{
File_WReverse(FOut, buf, j);
if(newline) fputchar(FOut, '\n', false);
j = 0;
}
}
while(c != EOF);
fclose(FOut);
fclose(FIn);
return 1;
}
File_WReverse(File:handle, const buf[], len) // This writes a string in reverse order. This is neccessary because our buffer is already reversed! Could be avoided by writing to the buffer in reversed order from the start
{
for(new i = len - 1; i >= 0; i --) fputchar(handle, buf[i], false);
}
Made this in a few minutes so if there are issues tell me (tests worked well).
Example usage:
Код:
File_LReverse("input.txt", "output.txt");