Okej, patnáctiletej beďatej tydýt se právě vyřádil.

Pevně doufám, že to budeš brát jenom jako návrh řešení a ne jako hotovou věc. Byl bych rád, kdyby sis všiml některých kontrol na selhání funkcí (např. scanf).
Soubor jsem změnil na /tmp/soubor.txt, kdybys jej hledal.
/*
* Projekt Bla
*
* Datové struktury katalogu.
*/
#ifndef PARAMETRY_H
#define PARAMETRY_H
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <malloc.h>
#include <string.h>
///////////////
// STRUKTURY //
///////////////
/// \brief položka seznamu
typedef struct katalog {
int radial_rychlost;
int jasnost;
int hmotnost;
char *nazev;
struct katalog *nasledujici;
} KATALOG;
//////////////////////
// PROTOTYPY FUNKCÍ //
//////////////////////
/// \brief Vytvoří položku spojového seznamu.
///
/// \param p_p_clanek Ukazatel k ukazateli článku.
/// \param rychlost Rychlost položky.
/// \param jas Jas položky.
/// \param hmotnost Hmotnost položky.
/// \param nazev Název položky.
/// \return EXIT_SUCCESS při úspěchu, EXIT_FAILURE při selhání.
int nova_polozka(KATALOG **p_p_clanek, int rychlost, int jas, int hmotnost, char *nazev);
/// \brief Smaže položku spojového seznamu.
///
/// POZOR: Na položku již nesmí být ukazováno.
///
/// \param p_clanek Článek ke smazání.
/// \return EXIT_SUCCESS při úspěchu, EXIT_FAILURE při selhání.
int smaz_polozku(KATALOG *p_clanek);
/// \brief Smaže katalog (spojový seznam).
///
/// \param p_clanek První článek seznamu.
/// \return EXIT_SUCCESS při úspěchu, EXIT_FAILURE při selhání.
int smaz_katalog(KATALOG *p_clanek);
/// \brief Vypíše na standardní výstup informace o položce.
///
/// \param p_clanek Ukazatel na položku.
void vypis_polozku(const KATALOG *p_clanek);
/// \brief Vypíše všechny položky z katalogu.
///
/// \param p_polozka Ukazatel na první položku.
void vypis_katalog(const KATALOG *p_clanek);
/////////////////////////
// IMPLEMENTACE FUNKCÍ //
/////////////////////////
int nova_polozka(KATALOG **p_p_clanek, int rychlost, int jas, int hmotnost, char *nazev) {
// -- deklarace -- //
KATALOG *p_clanek;
size_t nazev_delka;
char *nazev_kopie;
// -- kontrola argumentů -- //
if (p_p_clanek == NULL) {
fputs("CHYBA V PROGRAMU: nova_polozka() zavolána s NULL-ovým cílovým umístěním.\n", stderr);
return EXIT_FAILURE;
}
if (nazev == NULL) {
fputs("CHYBA V PROGRAMU: nova_polozka() zavolána s NULL-ovým názvem.\n", stderr);
return EXIT_FAILURE;
}
// -- zkopírování názvu -- //
// zjištění délky původního názvu ve znacích
nazev_delka = strlen(nazev);
// alokace kopie o délce počet znaků + null terminator
nazev_kopie = malloc(nazev_delka + 1);
// kontrola alokace
if (nazev_kopie == NULL) {
fputs("Chyba: nemohu alokovat pamet pro nazev polozky.\n", stderr);
return EXIT_FAILURE;
}
// samotné kopírování
strncpy(nazev_kopie, nazev, nazev_delka);
// kontrola na null terminator
nazev_kopie[nazev_delka] = '\0';
// -- vytvoření položky -- //
// alokace položky
p_clanek = (KATALOG *) malloc(sizeof(KATALOG));
// kontrola alokace
if(p_clanek == NULL) {
fputs("Chybna nemohu alokovat pamet pro datovou polozku.\n", stderr);
return EXIT_FAILURE;
}
// kopírování dat
p_clanek->radial_rychlost = rychlost;
p_clanek->jasnost = jas;
p_clanek->hmotnost = hmotnost;
p_clanek->nazev = nazev_kopie;
p_clanek->nasledujici = NULL;
// navrácení ukazatele na novou položku
*p_p_clanek = p_clanek;
return EXIT_SUCCESS;
};
int smaz_polozku(KATALOG *p_clanek) {
// -- kontrola argumentu -- //
if (p_clanek == NULL) {
fputs("CHYBA V PROGRAMU: smaz_polozku() zavolána s NULL-ovým pointerem.\n", stderr);
return EXIT_FAILURE;
}
// smazání kopie názvu
if (p_clanek->nazev != NULL)
free(p_clanek->nazev);
// smazání položky
free(p_clanek);
return EXIT_SUCCESS;
}
int smaz_katalog(KATALOG *p_katalog) {
KATALOG *p_clanek = p_katalog;
while (p_clanek != NULL) {
KATALOG *p_dalsi = p_clanek->nasledujici;
if (!smaz_polozku(p_clanek))
return EXIT_FAILURE;
p_clanek = p_dalsi;
}
}
void vypis_polozku(const KATALOG *p_clanek) {
// kontrola argumentů
if(p_clanek == NULL)
return;
// výpis na standardní výstup
printf("\"%s\":\n", p_clanek->nazev);
printf(" * Hmotnost: %d\n", p_clanek->hmotnost);
printf(" * Jasnost: %d\n", p_clanek->jasnost);
printf(" * Radialni rychlost: %d\n", p_clanek->radial_rychlost);
printf("\n");
};
void vypis_katalog(const KATALOG *p_katalog) {
const KATALOG *p_clanek = p_katalog;
int n = 1;
while (p_clanek != NULL) {
printf("%d. ", n++);
vypis_polozku(p_clanek);
p_clanek = p_clanek->nasledujici;
}
}
#endif
/*
* Projekt Bla
*
* Hlavní část programu.
*/
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include "parametry.h"
// maximální délka názvu
#define INPUT_BUFFER 256
//////////////////////
// PROTOTYPY FUNKCÍ //
//////////////////////
/// \brief Vstupní bod programu.
///
/// \return 0 při úspěchu, 1 při chybě.
int main(void);
/// \brief Přečte od uživatele číselnou hodnotu.
///
/// \param vyzva Výzva k zadání údaje.
/// \return Přečtené číslo.
int ziskej_cislo(const char *vyzva);
/// \brief Přečte od uživatele text.
///
/// \param vyzva Výzva k zadání údaje.
/// \param buffer Buffer pro uložení textu.
/// \param max Maximální počet přečtených znaků.
void ziskej_text(const char *vyzva, char *buffer, size_t max);
/// \brief Přečte všechny dostupné znaky ze standardního vstupu a zahodí je.
void vycisti_vstup(void);
/// \brief Vypíše exoplanety do souboru.
///
/// \param soubor Soubor, do kterého zapisovat.
/// \param p_katalog Katalog k vypsání.
/// \return EXIT_SUCCESS při úspěchu, EXIT_FAILURE při selhání.
void vypis_soubor(FILE *soubor, KATALOG *p_katalog);
/////////////////////////
// IMPLEMENTACE FUNKCÍ //
/////////////////////////
void vycisti_vstup(void) {
char ch;
do {
ch = getchar();
} while (ch != '\n' && ch != EOF);
}
int ziskej_cislo(const char *vyzva) {
int hodnota;
// opakuj, dokud nezískáš platnou hodnotu
while (1) {
int precteno;
if (vyzva != NULL) {
fputs(vyzva, stdout);
fflush(stdout);
}
precteno = scanf(" %d", &hodnota);
vycisti_vstup();
if (precteno == 1) {
break;
}
}
return hodnota;
}
void ziskej_text(const char *vyzva, char *buffer, size_t max) {
// stackoverflow: http://stackoverflow.com/a/4023921/1561345
size_t delka;
// opakuj, dokud nezískáš neprázdnou hodnotu
do {
if (vyzva != NULL) {
fputs(vyzva, stdout);
fflush(stdout);
}
} while (fgets(buffer, max, stdin) == NULL);
delka = strlen(buffer);
// pokud uživatel zadal příliš dlouhé jméno, je třeba odhodit zbytek v zásobě.
if (buffer[delka-1] != '\n') {
vycisti_vstup();
return;
}
// jinak jen ořízneme nový řádek.
buffer[delka-1] = '\0';
return;
}
void vypis_soubor(FILE *soubor, KATALOG *p_katalog) {
KATALOG *p_clanek = p_katalog;
while (p_clanek != NULL) {
fprintf(soubor, "%s,%d,%d,%d\n",
p_clanek->nazev,
p_clanek->hmotnost,
p_clanek->jasnost,
p_clanek->radial_rychlost);
p_clanek = p_clanek->nasledujici;
}
}
int main(void) {
FILE *fa = NULL;
KATALOG *p_katalog = NULL, *p_clanek_posledni = NULL;
int n = 1;
char vstup[INPUT_BUFFER];
// -- otevření souboru -- //
fa = fopen("/tmp/soubor.txt", "w");
if (fa == NULL) {
fprintf(stderr, "Nepodarilo se otevrit soubor: %s!\n", strerror(errno));
return EXIT_FAILURE;
}
printf("Soubor uspesne otevren!\n");
// -- čtení exoplanet ze standardního vstupu -- //
while(1) {
int rychlost, jasnost, hmotnost;
KATALOG *p_polozka = NULL;
printf("Exoplaneta cislo %i\n", n++);
ziskej_text("Zadejte nazev: \n", vstup, INPUT_BUFFER);
hmotnost = ziskej_cislo("Zadejte hmotnost: \n");
jasnost = ziskej_cislo("Zadejte jasnost: \n");
rychlost = ziskej_cislo("Zadejte radialni rychlost: \n");
if (nova_polozka(&p_polozka, rychlost, jasnost, hmotnost, vstup) == EXIT_FAILURE)
return EXIT_FAILURE;
// aktualizace ukazatelů
if (p_katalog == NULL) {
p_katalog = p_polozka;
}
if (p_clanek_posledni != NULL) {
p_clanek_posledni->nasledujici = p_polozka;
}
p_clanek_posledni = p_polozka;
// dotaz na pokračování
ziskej_text("Prejete si pridat dalsi exoplanety? [Y/n] ", vstup, INPUT_BUFFER);
if (strcmp(vstup, "n") == 0 || strcmp(vstup, "N") == 0)
break;
}
// -- výpis exoplanet na standardní výstup -- //
fputs("\nExoplanety:\n\n", stdout);
vypis_katalog(p_katalog);
// -- výpis exoplanet do souboru -- //
vypis_soubor(fa, p_katalog);
// -- smazání seznamu -- //
if (!smaz_katalog(p_katalog)) {
return EXIT_FAILURE;
}
// -- uzavření souboru -- //
if (fclose(fa) == EOF) {
printf("Soubor se nepodarilo uzavrit: %s.\n", strerror(errno));
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}