A simple solution to only remove any occurrence of CR or NL is
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
const char *remove_any_of = "\n\r";
int c;
while((c = getchar()) != EOF) {
if (!strchr(remove_any_of, c)) putchar(c);
}
return EXIT_SUCCESS;
}
Keep in mind that this works well for ASCII encoded text as well as UTF-8 encoded text, but not any other text.
The usage is as suggested by PIEBALDconsult as command line filter: consuming stdin and writing to stdout.
Alternatively, for not too large files, you could slurp the entire file into one memory buffer and process each character in that buffer, and finally dump the processed buffer back to the file. This will work fine since the file gets smaller and never larger than the original file - so you do not have to take care of allocating more space if needed.
Cheers
Andi
PS: A sample version for the alternative solution mentioned above (with full blown error handling) might be as follows. Have fun! :-)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *buffer;
size_t capacity;
size_t next_pos;
} pos_t;
pos_t slurp(const char *file_name)
{
pos_t pos = { NULL, 0, 0 };
FILE *file = fopen(file_name, "rb");
if (!file) {
perror("Failed to open file in read mode");
return pos;
}
if (fseek(file, 0, SEEK_END)) {
perror("Failed to go to the end of the file");
fclose(file);
return pos;
}
long size = ftell(file);
if (size < 0) {
perror("Failed to get the length of the file");
fclose(file);
return pos;
}
rewind(file);
char *slurped = malloc(size);
if (!slurped) {
perror("Failed to allocate memory");
fclose(file);
return pos;
}
if (fread(slurped, 1, size, file) != size) {
perror("Failed to slurp the file");
free(slurped);
fclose(file);
return pos;
}
fclose(file);
pos.buffer = slurped;
pos.capacity = size;
printf("slurp: %s = %ld bytes\n", file_name, size);
return pos;
}
void dump(const char *file_name, pos_t *pos)
{
FILE *file = fopen(file_name, "wb");
if (!file) {
perror("Failed to open file in write mode");
return;
}
if (fwrite(pos->buffer, 1, pos->next_pos, file) != pos->next_pos) {
perror("Failed to write to the file");
fclose(file);
return;
}
if (fclose(file)) {
perror("Failed to close file");
return;
}
printf("dump: %s = %ld bytes\n", file_name, pos->next_pos);
}
int read_char(pos_t *pos)
{
if (pos->capacity <= pos->next_pos) return EOF;
return pos->buffer[pos->next_pos++];
}
void write_char(char c, pos_t *pos)
{
if (pos->capacity <= pos->next_pos) return;
pos->buffer[pos->next_pos++] = c;
}
int main(unsigned int argc, const char *argv[])
{
if (argc < 2) {
printf("Missing file name\n");
return EXIT_FAILURE;
}
const char *file_name = argv[1];
pos_t read = slurp(file_name);
pos_t write = read; if (read.capacity == 0) {
printf("Rejected to process file %s\n", file_name);
return EXIT_FAILURE;
}
const char *remove_any_of = "\n\r";
int c;
while((c = read_char(&read)) != EOF) {
if (!strchr(remove_any_of, c)) write_char(c, &write);
}
dump(file_name, &write);
free(read.buffer);
return EXIT_SUCCESS;
}