/* C11. Text-record round trip through an automatically removed temporary file. */
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct { int roll; char name[24]; double mark; } Student;
int main(void)
{
    const Student original[] = {{101, "Asha", 84.5}, {102, "Ravi", 91.0}};
    FILE *file = tmpfile(); /* No named user file is overwritten. */
    if (file == NULL) { perror("tmpfile"); return EXIT_FAILURE; }
    for (size_t i = 0; i < 2; ++i) {
        if (fprintf(file, "%d\t%s\t%.1f\n", original[i].roll,
                    original[i].name, original[i].mark) < 0) {
            perror("write record"); fclose(file); return EXIT_FAILURE;
        }
    }
    /* Positioning is required when switching an update stream from write to read. */
    if (fflush(file) == EOF || fseek(file, 0, SEEK_SET) != 0) {
        perror("prepare read"); fclose(file); return EXIT_FAILURE;
    }
    for (size_t i = 0; i < 2; ++i) {
        Student recovered;
        if (fscanf(file, "%d %23s %lf", &recovered.roll,
                   recovered.name, &recovered.mark) != 3) {
            fputs("Could not read a complete record\n", stderr);
            fclose(file); return EXIT_FAILURE;
        }
        assert(recovered.roll == original[i].roll);
        assert(strcmp(recovered.name, original[i].name) == 0);
        assert(recovered.mark == original[i].mark);
        printf("%d %s %.1f\n", recovered.roll, recovered.name, recovered.mark);
    }
    int extra;
    if (fscanf(file, " %d", &extra) != EOF || ferror(file)) {
        fputs("Unexpected trailing data or read error\n", stderr);
        fclose(file); return EXIT_FAILURE;
    }
    if (fclose(file) == EOF) { perror("close temporary file"); return EXIT_FAILURE; }
    puts("file-record tests passed");
    return EXIT_SUCCESS;
}
