Andreas Gieriet
Простым решением для удаления только любого вхождения CR или NL является
#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;
}
Имейте в виду, что это хорошо работает для текста в кодировке ASCII, а также для текста в кодировке UTF-8, но не для любого другого текста.
Использование в качестве фильтра командной строки предлагается PIEBALDconsult: потребление stdin и запись в stdout.
В качестве альтернативы для не слишком больших файлов вы можете поместить весь файл в один буфер памяти и обработать каждый символ в этом буфере, а затем сбросить обработанный буфер обратно в файл. Это будет работать нормально, так как файл становится меньше и никогда не больше исходного файла - так что вам не придется заботиться о выделении большего пространства, если это необходимо.
Овации
Энди
PS: примерная версия альтернативного решения, упомянутого выше (с полномасштабной обработкой ошибок), может быть следующей. Получайте удовольствие! :-)
#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;
}