Текстовый файл с вещественными числами сравнить с числами массива - C (СИ)
Формулировка задачи:
Решение задачи: «Текстовый файл с вещественными числами сравнить с числами массива»
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define EPS (1.0e-6)
typedef struct SET {
double value;
struct SET * next;
} node_t, *set_t;
int set_add(set_t * pSet, const double value) {
if ( *pSet ) {
if ( fabs((*pSet)->value - value) < EPS )
return 0;
return set_add(&((*pSet)->next), value);
}
else {
if ( ! ( *pSet = malloc(sizeof(node_t)) ) )
return -1;
(*pSet)->value = value;
(*pSet)->next = NULL;
return 0;
}
}
int set_dump(set_t set, FILE * fout) {
while ( set ) {
if ( fprintf(fout, "%f\n", set->value) < 0 )
return -1;
set = set->next;
}
return 0;
}
void set_free(set_t * pSet) {
if ( *pSet ) {
set_free(&((*pSet)->next));
free(*pSet);
*pSet = NULL;
}
}
#define PROGRAM_NAME argv[0]
#define INPUT_FILE_NAME argv[1]
#define OUTPUT_FILE_NAME argv[2]
int main(int argc, char ** argv) {
FILE * fin, * fout;
double value;
set_t set = NULL;
if ( argc < 3 ) {
fprintf(stderr, "USAGE: %s <input_file> <output_file>\n", PROGRAM_NAME);
exit(EXIT_FAILURE);
}
if ( ! ( fin = fopen(INPUT_FILE_NAME, "r") ) ) {
fprintf(stderr, "%s: can't open file %s for input!\n", PROGRAM_NAME, INPUT_FILE_NAME);
exit(EXIT_FAILURE);
}
while ( fscanf(fin, "%lf", &value) == 1 ) {
if ( set_add(&set, value) ) {
fprintf(stderr, "%s: memory error!\n", PROGRAM_NAME);
fclose(fin);
exit(EXIT_FAILURE);
}
}
if ( ferror(fin) || fclose(fin) ) {
fprintf(stderr, "%s: error while read input file!\n", PROGRAM_NAME);
set_free(&set);
exit(EXIT_FAILURE);
}
if ( ! ( fout = fopen(OUTPUT_FILE_NAME, "w") ) ) {
fprintf(stderr, "%s: can't open file %s for output!\n", PROGRAM_NAME, OUTPUT_FILE_NAME);
set_free(&set);
exit(EXIT_FAILURE);
}
if ( set_dump(set, fout) ) {
fprintf(stderr, "%s: error while write to output file!\n", PROGRAM_NAME);
set_free(&set);
if ( fclose(fout) )
fprintf(stderr, "%s: can't properly close output file!\n", PROGRAM_NAME);
exit(EXIT_FAILURE);
}
set_free(&set);
if ( fclose(fout) ) {
fprintf(stderr, "%s: can't properly close output file!\n", PROGRAM_NAME);
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
Объяснение кода листинга программы
Код представляет собой программу, которая читает вещественные числа из текстового файла и добавляет их в связанный список. Затем программа записывает содержимое списка в другой файл. Если во время чтения или записи возникают ошибки, программа выводит сообщение об ошибке и завершает работу с неудачным статусом.
Список содержит элементы типа node_t, которые представляют собой структуры, состоящие из одного вещественного числа и указателя на следующий элемент списка.
Список реализован с помощью динамической памяти, что означает, что его размер может изменяться во время выполнения программы.
В начале кода определены макросы для удобного доступа к аргументам командной строки.
Программа принимает три аргумента: имя входного файла, имя выходного файла и имя программы.
В функции main открывается входной файл для чтения и выходной файл для записи.
Затем программа читает вещественные числа из входного файла и добавляет их в список с помощью функции set_add.
Когда достигается конец входного файла, программа закрывает его и открывает выходной файл для записи.
Затем программа записывает содержимое списка в выходной файл с помощью функции set_dump.
После завершения записи программа закрывает выходной файл и завершает работу с успешным статусом.