Click here to Skip to main content
15,888,351 members
Please Sign up or sign in to vote.
2.00/5 (2 votes)
See more:
hey friends
I want delete "carriage return " and "line feed" on my *file :)
thnx

What I have tried:

I nothing tried I just want idea
Posted
Updated 17-Jun-16 12:46pm
Comments
PIEBALDconsult 16-Jun-16 21:55pm    
What you suggest may be too limited in utility. I recommend implementing a "filter" that you can pipe a stream through rather than requiring a file.
Further, you might want to have it accept parameters to specify the details of its operation.
Even better if you allow Regular Expressions.
Consider:
TYPE oldfile.txt | REPLACECHARS "\r\n" " " > newfile.txt
I have written such a thing and I use it for a number of tasks, not just removing "new lines".
Andreas Gieriet 17-Jun-16 18:09pm    
That's the UNIX tr command, right? I sometimes wonder why one has to re-invent such a tool on Windows environments...
Cheers
Andi

A simple solution to only remove any occurrence of CR or NL is
C
#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! :-)
C
#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; // share the buffer
    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;
}
 
Share this answer
 
v3
It's hard to do in any simple way in a single file, by one simple reason. Let's say, you have a big file, and you remove one character at the very beginning. As the rest of the content is shifted, it means that you have to rewrite the whole content of the file. This is exactly what's going to happen with ends of lines.

It should bring you to the next idea: if you have to rewrite the file (except perhaps a small portion before the first end-of-line), you have to admit it and rewrite it. The adequate solution is: open a source file as read-only, a new temporary file as write-only, and write all the content of the source file into a temporary file, skipping just the end-of-line characters. You can do it in some chunks of data (say, 1M) and remove unwanted characters from the string before copying it, using some string replacement method. If you want simplicity, the chunk could be one character.

When this is done, you can close the original and temporary files and then rename (move) the temporary file to the original file name, effectively discarding old version of it and the temporary file.

And now, one little problem is: what is the "end of line". Unfortunately, the ugly fact of nature is: this is a platform-dependent string. Please see: Newline — Wikipedia, the free encyclopedia.

In practice, you can ignore the possibility if having abnormally placed end-of-line characters and simply remove them all, which means removing all 0xA and 0xD characters. You may also want to remove rarely used Unicode separator characters.

—SA
 
Share this answer
 
v2
Comments
PIEBALDconsult 16-Jun-16 21:46pm    
And maybe replace the "newline sequence" with a SPACE if appropriate.
Sergey Alexandrovich Kryukov 16-Jun-16 22:07pm    
Well, the inquirer said "delete", so it's "delete". But can we ever be sure that our inquirer really knows what should be done?
—SA
PIEBALDconsult 16-Jun-16 22:16pm    
'ardly h'ever.
Richard MacCutchan 17-Jun-16 4:51am    
... used a big, big D?
PIEBALDconsult 17-Jun-16 9:24am    
:thumbsup:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900