Why does fprintf behave differently in text mode compared to a properly set carriage return in normal mode?

StackOverflow https://stackoverflow.com/questions/19298269

Question

The following question is more a curiosity than a problem.

I stumbled over this question, offering two different answers which seem to be equivalent. But they aren't, what made me thinking.

Imagine a system call which echoes two lines:

[~,message] = system( 'echo hello && echo world' );

returns:

hello
world

If one wants to write these lines to a .txt-file and open it in notepad, the common approach would be:

fid = fopen([pwd '\helloworld.txt'],'w');
fprintf(fid, '%s\n', message);
fclose(fid);
winopen('helloworld.txt')

which returns

hello world

As notepad obviously is not able to recognize the line feed \n properly, the solution is to use 'wt' instead of 'w' to enforce text mode, which is supposed to be slow. return:

hello
world

The documentation to fopen permissions says:

To open files in text mode, attach the letter 't' to the permission argument, such as 'rt' or 'wt+'.

On Windows® systems, in text mode:
-Read operations that encounter a carriage return followed by a newline character ('\r\n') remove the carriage return from the input.

-Write operations insert a carriage return before any newline character in the output.

So in my understanding it basically does:

fprintf(fid, '%s\r\n', message)

but the output again is:

hello world

What else does 'wt'? How could one obtain the same behavior with 'w'? I'm sorry if this question is meaningless and trivial, but after some frustrating hours I'm just curious what I was missing.

Was it helpful?

Solution

In my understanding it does

fprintf(fid, '%s', strrep(message, sprintf('\n'), sprintf('\r\n'))

If you do

fprintf(fid, '%s\r\n', message)

you're only adding one carriage return and a newline at the very end of your message, which is after "world\n".The newline character between "hello" and "world" remains without carriage return.

So in your fprintf your message is "hello\nworld\n\r\n", where it should be "hello\r\nworld\r\n"

You can check this by reading the output file in bytes, knowing that \n will be a 10 as uint8 and \r a 13:

>> fid = fopen('test.txt','wt');
>> fprintf(fid, 'hello\nworld\n');
>> fclose(fid);
>> fid = fopen('test.txt','r');
>> bytes = fread(fid, Inf, 'uint8')'

bytes =

   104   101   108   108   111    13    10   119   111   114   108   100    13    10
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top