how can I merge 2 empty lines into one? Like cat -s
#include <stdio.h>
#include <stdlib.h>
int main() {
int c;
FILE *file = fopen("2.txt", "r");
while ((c = getc(file)) != EOF) {
putc(c, stdout);
}
fclose(file);
return 0;
}
CodePudding user response:
Here is a modified version that implements cat -s
:
#include <stdio.h>
int main() {
int c, last_c = '\n', has_empty = 0;
FILE *file = fopen("2.txt", "r");
if (file != NULL) {
while ((c = getc(file)) != EOF) {
if (last_c == '\n' && c == '\n') {
if (has_empty) {
//has_empty = 0;
continue;
}
has_empty = 1;
} else {
has_empty = 0;
}
putchar(c);
last_c = c;
}
fclose(file);
}
return 0;
}
If you want to only collapse 2 empty lines into one, uncomment the //has_empty = 0;
statement.
CodePudding user response:
Consider using fgets()
instead, keep a copy of the last line and discard any empty line if the stored line is also empty.
But if you need to use getc()
, we run in a bit of trouble because of the way the different OSs handle new lines. Windows uses \r\n
but Linux and MacOS use \n
.
Linux or MacOS
For Linux or MacOS, you simply need to keep a copy of the last character and discard any newline if the last character is also a newline :
#include <stdio.h>
#include <stdlib.h>
int main() {
int c;
int last_c = '\0';
FILE *file = fopen("2.txt","r");
while ((c = getc(file)) != EOF)
{
if(last_c == '\n' && c == '\n')
continue;
putc(c, stdout);
last_c = c;
}
fclose(file);
return 0;
}
Windows
For Windows it can be a bit trickier. First you can have invalid new lines with single \r
or \n
. But most importantly we need to check two characters to make sure it is a new line. We can check for a newline and set a flag, then discard any newline sequence. We need to look ahead if we encountered a newline, and determinate if it is a single \r
or if it is followed by a \n
. Then if it is not a newline sequence we need to print the \r
we skipped.
A simple implementation would look like this :
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main() {
int c;
int last_c = '\0';
bool is_newline = 0;
FILE *file = fopen("2.txt","r");
while ((c = getc(file)) != EOF)
{
if(is_newline)
{
if(c == '\n' && last_c == '\r' || c == '\r')
{
last_c = c;
continue;
}
else
{
if(last_c == '\r')
putc(c, stdout); //Print the '\r' we skipped
is_newline = false;
}
}
putc(c, stdout);
if(c == '\n' && last_c == '\r')
is_newline = true;
last_c = c;
}
fclose(file);
return 0;
}
This code will let the \n
or \r
that are alone pass through without touching them, but will delete newlines that repeat