Diagnostics
The logic looks correct if you have line endings on Unix. If you have Windows CRLF line endings, but they process the file on Unix, you have CR before each LF, and CR resets newLine to zero, so you get a message for every new line.
This explains what you see.
It also explains why everyone else says your logic is correct (this is assuming the lines end only with LF, not CRLF), but you see an unexpected result.
How to solve it?
Fair question. One of the main options is to use dos2unix or an equivalent mechanism to convert a DOS file to a Unix file. There are many questions on SO on this.
If you don't need CR characters at all ( '\r' in C), you can just delete (don't print, not newLine zero)).
If you need to keep CRLF line endings you need to be a little more careful. You will need to write that you have CR, and then check that you get LF, then print the pair, and then check if you get more CRLF sequences and suppress them, etc.
Working code - dupnl.c
This program reads only from standard input; it is more flexible than just reading from a fixed file name. Learn to avoid writing code that works with only one file name; it will save you a lot of recompilation over time. Th-code processes Unix-style files with newlines ( "\n" ) at the end; it also processes DOS files with CRLF ends ( "\r\n" ); and it also processes (old style) Mac files (Mac OS 9 and earlier) with CR ( "\r" ). In fact, it allows you to randomly mix different styles of line endings. If you want the mode, you have to do some work to decide which mode, and then use the appropriate subset of this code.
#include <stdio.h> int main(void) { FILE *fp = stdin; // Instead of fopen() int newLine = 1; int c; while ((c = fgetc(fp)) != EOF) { if (c == '\n') { /* Unix NL line ending */ if (newLine++ == 0) putchar(c); } else if (c == '\r') { int c1 = fgetc(fp); if (c1 == '\n') { /* DOS CRLF line ending */ if (newLine++ == 0) { putchar(c); putchar(c1); } } else { /* MAC CR line ending */ if (newLine++ == 0) putchar(c); if (c1 != EOF && c1 != '\r') ungetc(c1, stdin); } } else { putchar(c); newLine = 0; } } return 0; }
Run example - inputs and outputs
$ cat test.unx data long enough to be seen 1 - Unix data long enough to be seen 2 - Unix data long enough to be seen 3 - Unix data long enough to be seen 4 - Unix data long enough to be seen 5 - Unix $ sed 's/Unix/DOS/g' test.unx | ule -d > test.dos $ cat test.dos data long enough to be seen 1 - DOS data long enough to be seen 2 - DOS data long enough to be seen 3 - DOS data long enough to be seen 4 - DOS data long enough to be seen 5 - DOS $ sed 's/Unix/Mac/g' test.unx | ule -m > test.mac $ cat test.mac $ ta long enough to be seen 5 - Mac $ odx test.mac 0x0000: 0D 0D 64 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 ..data long enou 0x0010: 67 68 20 74 6F 20 62 65 20 73 65 65 6E 20 31 20 gh to be seen 1 0x0020: 2D 20 4D 61 63 0D 0D 64 61 74 61 20 6C 6F 6E 67 - Mac..data long 0x0030: 20 65 6E 6F 75 67 68 20 74 6F 20 62 65 20 73 65 enough to be se 0x0040: 65 6E 20 32 20 2D 20 4D 61 63 0D 64 61 74 61 20 en 2 - Mac.data 0x0050: 6C 6F 6E 67 20 65 6E 6F 75 67 68 20 74 6F 20 62 long enough to b 0x0060: 65 20 73 65 65 6E 20 33 20 2D 20 4D 61 63 0D 64 e seen 3 - Mac.d 0x0070: 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 20 ata long enough 0x0080: 74 6F 20 62 65 20 73 65 65 6E 20 34 20 2D 20 4D to be seen 4 - M 0x0090: 61 63 0D 0D 0D 0D 64 61 74 61 20 6C 6F 6E 67 20 ac....data long 0x00A0: 65 6E 6F 75 67 68 20 74 6F 20 62 65 20 73 65 65 enough to be see 0x00B0: 6E 20 35 20 2D 20 4D 61 63 0D 0D 0D n 5 - Mac... 0x00BC: $ dupnl < test.unx data long enough to be seen 1 - Unix data long enough to be seen 2 - Unix data long enough to be seen 3 - Unix data long enough to be seen 4 - Unix data long enough to be seen 5 - Unix $ dupnl < test.dos data long enough to be seen 1 - DOS data long enough to be seen 2 - DOS data long enough to be seen 3 - DOS data long enough to be seen 4 - DOS data long enough to be seen 5 - DOS $ dupnl < test.mac $ ta long enough to be seen 5 - Mac $ dupnl < test.mac | odx 0x0000: 64 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 data long enough 0x0010: 20 74 6F 20 62 65 20 73 65 65 6E 20 31 20 2D 20 to be seen 1 - 0x0020: 4D 61 63 0D 64 61 74 61 20 6C 6F 6E 67 20 65 6E Mac.data long en 0x0030: 6F 75 67 68 20 74 6F 20 62 65 20 73 65 65 6E 20 ough to be seen 0x0040: 32 20 2D 20 4D 61 63 0D 64 61 74 61 20 6C 6F 6E 2 - Mac.data lon 0x0050: 67 20 65 6E 6F 75 67 68 20 74 6F 20 62 65 20 73 g enough to be s 0x0060: 65 65 6E 20 33 20 2D 20 4D 61 63 0D 64 61 74 61 een 3 - Mac.data 0x0070: 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 20 74 6F 20 long enough to 0x0080: 62 65 20 73 65 65 6E 20 34 20 2D 20 4D 61 63 0D be seen 4 - Mac. 0x0090: 64 61 74 61 20 6C 6F 6E 67 20 65 6E 6F 75 67 68 data long enough 0x00A0: 20 74 6F 20 62 65 20 73 65 65 6E 20 35 20 2D 20 to be seen 5 - 0x00B0: 4D 61 63 0D Mac. 0x00B4: $
Lines starting with $ ta where the prompt overwrites the previous output (and the "long enough to be visible" part, because my hint is usually longer than just $ ).
odx is a hex dump program. ule is for “uniform line endings” and parses or converts data to have uniform line endings.
Usage: ule [-cdhmnsuzV] [file ...] -c Check line endings (default) -d Convert to DOS (CRLF) line endings -h Print this help and exit -m Convert to MAC (CR) line endings -n Ensure line ending at end of file -s Write output to standard output (default) -u Convert to Unix (LF) line endings -z Check for zero (null) bytes -V Print version information and exit