Náplňou týchto úloh je precvičiť si prácu so štruktúrami v jazyku C. Úlohy sú definované pre vyskúšanie si štruktúr v rôznych prípadoch použitia a práce s nimi.
Pri vypracovaní úloh použite všetky doterajšie znalosti, hlavne z tématiky polí a alokovania pamäte.
týchto úloh odporúčam mať funkčné lokálne vývojové prostredie (VS Code, CLion a pod.) a kompilátor jazyka C.
Riešenia na jednotlivé úlohy budú uverejnené neskôr.
Napíšte program, zdrojový kód, v jazyku C použitím štandardu C11, ktorý vytvorí štruktúru na reprezentáciu študenta. Táto štruktúra by mala obsahovať nasledujúce položky: meno (pole znakov), vek (celé číslo), priemerný prospech (desatinné číslo). Program by mal načítať údaje študentov, vypočítať priemerný vek a priemerný prospech všetkých študentov a tieto hodnoty vypísať.
Vstupy programu môžu byť zadané zo štandardného vstupu alebo načítané zo súboru.
Pre nasledujúce vstupy programu:
1. Študent
Meno: Ján
Vek: 20
Priemerný prospech: 1.5
---
2. Študent
Meno: Petra
Vek: 22
Priemerný prospech: 1.8
---
3. Študent
Meno: Milan
Vek: 19
Priemerný prospech: 2.0
---
Program vypíše na štandardný výstup nasledovný výstup:
Sumár študentov:
Priemerný vek: 20.33 Priemerný prospech: 1.77
#include <stdio.h>
#include <stdlib.h>
#define MAX_NAME_LENGTH 50
// Definícia štruktúry pre reprezentáciu študenta
typedef struct {
char name[MAX_NAME_LENGTH];
int age;
float averageGrade;
} Student;
int main() {
int numStudents;
printf("Zadajte počet študentov: ");
scanf("%d", &numStudents);
if (numStudents <= 0) {
printf("Počet študentov musí byť kladné číslo.\n");
return 1;
}
// Dynamická alokácia poľa študentov
Student *students = (Student *)malloc(numStudents * sizeof(Student));
if (students == NULL) {
printf("Nepodarilo sa alokovať pamäť.\n");
return 1;
}
// Načítanie údajov študentov
for (int i = 0; i < numStudents; i++) {
printf("\n%d. Študent\n", i + 1);
printf("Meno: ");
scanf(" %49s", students[i].name); // Obmedzenie na MAX_NAME_LENGTH - 1 znakov
printf("Vek: ");
scanf("%d", &students[i].age);
printf("Priemerný prospech: ");
scanf("%f", &students[i].averageGrade);
}
// Výpočet priemerného veku a priemerného prospechu
float totalAge = 0, totalGrade = 0;
for (int i = 0; i < numStudents; i++) {
totalAge += students[i].age;
totalGrade += students[i].averageGrade;
}
float averageAge = totalAge / numStudents;
float averageGrade = totalGrade / numStudents;
// Výpis výsledkov
printf("\nSumár študentov:\n");
printf("Priemerný vek: %.2f\n", averageAge);
printf("Priemerný prospech: %.2f\n", averageGrade);
// Uvoľnenie pamäte
free(students);
return 0;
}
Napíšte program, zdrojový kód, v jazyku C použitím štandardu C11, ktorý vytvorí štruktúru na reprezentáciu zamestnanca. Štruktúra by mala obsahovať meno (pole znakov), identifikačné číslo (celé číslo) a plat (desatinné číslo). Program by mal načítať údaje pre niekoľko zamestnancov, zoradiť ich podľa platu zostupne a vypísať zoznam zamestnancov spolu s ich platmi. Následne program vypíše priemerný plat zamestnancov.
Údaje o zamestnancoch načítajte zo súboru, kde na jednom riadku je definovaný jeden zamestnanec a hodnoty na riadku sú oddelené medzerou: ID Meno Plat
Cestu k súboru načítajte od používateľa zo štandardného vstupu na začiatku programu.
Program pre vstupný súbor:
101 Anna 2500.50
102 Peter 3000.75
103 Lucia 2800.00
vypíše nasledovný text na výstupe:
102 Peter 3000.75
103 Lucia 2800.00
101 Anna 2500.50
---
Priemerný plat: 2767.08
Skúste upraviť výpis tak aby mal formát tabuľky. Nezabudnite na správne zarovnanie stĺpcov. Takýto výstup by mohol vyzerať nasledovne:
|ID |Meno |Plat |
|----|------|--------|
|102 |Peter |3000.75 |
|103 |Lucia |2800.00 |
|101 |Anna |2500.50 |
---
Priemerný plat: 2767.08
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NAME_LENGTH 50
#define MAX_EMPLOYEES 100
// Definícia štruktúry na reprezentáciu zamestnanca
typedef struct {
int id;
char name[MAX_NAME_LENGTH];
float salary;
} Employee;
// Funkcia na porovnanie zamestnancov podľa platu (pre qsort)
int compareBySalaryDescending(const void *a, const void *b) {
float salaryA = ((Employee *)a)->salary;
float salaryB = ((Employee *)b)->salary;
if (salaryA < salaryB) return 1;
if (salaryA > salaryB) return -1;
return 0;
}
int main() {
char filePath[100];
Employee employees[MAX_EMPLOYEES];
int count = 0;
// Načítanie cesty k súboru
printf("Zadajte cestu k súboru: ");
scanf("%s", filePath);
// Otvorenie súboru
FILE *file = fopen(filePath, "r");
if (file == NULL) {
printf("Nepodarilo sa otvoriť súbor.\n");
return 1;
}
// Načítanie údajov zo súboru
while (fscanf(file, "%d %49s %f", &employees[count].id, employees[count].name, &employees[count].salary) == 3) {
count++;
if (count >= MAX_EMPLOYEES) {
printf("Dosiahnutý maximálny počet zamestnancov (%d).\n", MAX_EMPLOYEES);
break;
}
}
fclose(file);
if (count == 0) {
printf("Súbor neobsahuje žiadne údaje o zamestnancoch.\n");
return 1;
}
// Zoradenie zamestnancov podľa platu zostupne
qsort(employees, count, sizeof(Employee), compareBySalaryDescending);
// Výpočet priemerného platu
float totalSalary = 0;
for (int i = 0; i < count; i++) {
totalSalary += employees[i].salary;
}
float averageSalary = totalSalary / count;
// Výpis zamestnancov
printf("\n");
for (int i = 0; i < count; i++) {
printf("%d %s %.2f\n", employees[i].id, employees[i].name, employees[i].salary);
}
// Výpis priemerného platu
printf("---\n");
printf("Priemerný plat: %.2f\n", averageSalary);
return 0;
}
Napíšte program, zdrojový kód, v jazyku C použitím štandardu C11, ktorý definuje štruktúru na reprezentáciu dátumu s položkami deň, mesiac a rok (celé čísla). Program by mal umožniť používateľovi zadať dva dátumy kde jednotlivé hodnoty dátumov sú definované v jednom riadku oddelené medzerou a vypočítať rozdiel medzi nimi. Rozdieľ je vypísaný ako počet dní medzi dátumami.
V programe ošetrite vstup od používateľa aby bolo možné zadať iba správny dátum (napríklad nie je možné zadať 31.2.) a zohľadňuje priestupné roky.
Priebeh programu môže vyzerať nasledovne:
Prvý dátum: 1 1 2023
Druhý dátum: 15 1 2024
---
Rozdiel dátumov: 376 dní
Prvý dátum: 28 2 2020
Druhý dátum: 1 3 2020
---
Rozdiel dátumov: 2 dni
Skúste upraviť výpis rozdielu dátumov tak aby uviedol pre používateľa rozdiel aj koľko prípadných rokov, mesiacov, či dní je medzi dátumami. Napríklad:
#include <stdio.h>
#include <stdlib.h>
// Štruktúra na reprezentáciu dátumu
typedef struct {
int day;
int month;
int year;
} Date;
// Počet dní v mesiacoch (pre bežné a priestupné roky)
const int daysInMonth[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, // Bežný rok
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} // Priestupný rok
};
// Funkcia na kontrolu, či je rok priestupný
int isLeapYear(int year) {
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
}
// Funkcia na validáciu dátumu
int isValidDate(Date date) {
if (date.year < 1 || date.month < 1 || date.month > 12 || date.day < 1) {
return 0;
}
int leap = isLeapYear(date.year);
if (date.day > daysInMonth[leap][date.month - 1]) {
return 0;
}
return 1;
}
// Funkcia na prepočet dátumu na počet dní od začiatku referenčného bodu (napr. 1.1.0001)
int dateToDays(Date date) {
int totalDays = 0;
// Pridanie dní za celé roky
for (int i = 1; i < date.year; i++) {
totalDays += isLeapYear(i) ? 366 : 365;
}
// Pridanie dní za celé mesiace v aktuálnom roku
int leap = isLeapYear(date.year);
for (int i = 0; i < date.month - 1; i++) {
totalDays += daysInMonth[leap][i];
}
// Pridanie dní v aktuálnom mesiaci
totalDays += date.day;
return totalDays;
}
// Funkcia na výpočet rozdielu medzi dvoma dátumami
int calculateDateDifference(Date date1, Date date2) {
int days1 = dateToDays(date1);
int days2 = dateToDays(date2);
return abs(days1 - days2);
}
int main() {
Date date1, date2;
// Načítanie prvého dátumu
printf("Prvý dátum (deň mesiac rok): ");
scanf("%d %d %d", &date1.day, &date1.month, &date1.year);
if (!isValidDate(date1)) {
printf("Neplatný dátum! Zadajte správny dátum.\n");
return 1;
}
// Načítanie druhého dátumu
printf("Druhý dátum (deň mesiac rok): ");
scanf("%d %d %d", &date2.day, &date2.month, &date2.year);
if (!isValidDate(date2)) {
printf("Neplatný dátum! Zadajte správny dátum.\n");
return 1;
}
// Výpočet a výpis rozdielu
int difference = calculateDateDifference(date1, date2);
printf("---\nRozdiel dátumov: %d dní\n", difference);
return 0;
}
Napíšte program, zdrojový kód, v jazyku C použitím štandardu C11, ktorý vytvorí štruktúru na reprezentáciu knihy v knižnici. Štruktúra by mala obsahovať názov (pole znakov), autora (pole znakov) a rok vydania (celé číslo). Program by mal načítať údaje zo súboru kde je definovaná kniha na jednom riadku a hodnoty štruktúry sú oddelené bodkočiarkou. Vstupný súbor môže byť v rovnakom priečinku ako program a môže mať napevno definovaný názov v zdrojovom kóde. Program po úspešnom spracovaní súboru vypíše počet načítaných kníh. Program následne umožní zadať používateľovi rok a vypíše knihy, ktoré boli vydané v zadanom roku.
Vstupný súbor s knihami
Programovanie v C;Kernighan & Ritchie;1988
Moderné algoritmy;Jon Bentley;1990
Umenie programovania;Donald Knuth;1968
Štruktúra a interpretácia počítačových programov;Harold Abelson & Gerald Jay Sussman;1985
Cvičenia z programovania;Brian Kernighan;1988
Algoritmy v C++;Robert Sedgewick;1990
Čistý kód;Robert C. Martin;2008
Pragmatický programátor;Andrew Hunt & David Thomas;1999
Python pre začiatočníkov;Guido van Rossum;2000
Počítačová grafika;John F. Hughes & James D. Foley;1995
Priebeh programu môže byť nasledovný:
Počet kníh v databáze: 10
Zadajte rok vydania kníh: 1990
Názov: Moderné algoritmy
Autor: Jon Bentley
Rok vydania: 1990
---
Názov: Algoritmy v C++
Autor: Robert Sedgewick
Rok vydania: 1990
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_TITLE_LENGTH 100
#define MAX_AUTHOR_LENGTH 100
#define MAX_BOOKS 100
// Štruktúra na reprezentáciu knihy
typedef struct {
char title[MAX_TITLE_LENGTH];
char author[MAX_AUTHOR_LENGTH];
int year;
} Book;
// Funkcia na načítanie údajov zo súboru
int loadBooks(const char *filename, Book books[]) {
FILE *file = fopen(filename, "r");
if (file == NULL) {
printf("Nepodarilo sa otvoriť súbor %s.\n", filename);
return -1;
}
int count = 0;
char line[256];
while (fgets(line, sizeof(line), file)) {
if (count >= MAX_BOOKS) {
printf("Dosiahnutý maximálny počet kníh (%d).\n", MAX_BOOKS);
break;
}
// Odstránenie nového riadku na konci
line[strcspn(line, "\n")] = '\0';
// Rozdelenie riadku podľa bodkočiarky
char *token = strtok(line, ";");
if (token != NULL) {
strncpy(books[count].title, token, MAX_TITLE_LENGTH - 1);
books[count].title[MAX_TITLE_LENGTH - 1] = '\0';
}
token = strtok(NULL, ";");
if (token != NULL) {
strncpy(books[count].author, token, MAX_AUTHOR_LENGTH - 1);
books[count].author[MAX_AUTHOR_LENGTH - 1] = '\0';
}
token = strtok(NULL, ";");
if (token != NULL) {
books[count].year = atoi(token);
}
count++;
}
fclose(file);
return count;
}
// Funkcia na vyhľadanie a výpis kníh podľa roku
void printBooksByYear(Book books[], int count, int year) {
int found = 0;
for (int i = 0; i < count; i++) {
if (books[i].year == year) {
printf("Názov: %s\n", books[i].title);
printf("Autor: %s\n", books[i].author);
printf("Rok vydania: %d\n", books[i].year);
printf("---\n");
found = 1;
}
}
if (!found) {
printf("Žiadne knihy z roku %d.\n", year);
}
}
int main() {
Book books[MAX_BOOKS];
const char *filename = "books.txt";
// Načítanie kníh zo súboru
int bookCount = loadBooks(filename, books);
if (bookCount < 0) {
return 1; // Chyba pri načítaní
}
printf("Počet kníh v databáze: %d\n", bookCount);
// Zadanie roku od používateľa
int year;
printf("Zadajte rok vydania kníh: ");
scanf("%d", &year);
// Výpis kníh podľa roku
printBooksByYear(books, bookCount, year);
return 0;
}
Napíšte program, zdrojový kód, v jazyku C použitím štandardu C11, ktorý implementuje jednoduchý zreťazený zoznam pomocou štruktúr. Každý prvok zoznamu by mal obsahovať celé kladné číslo a pointer na ďalší prvok. Program umožní používateľovi cez štandardný vstup zadať číslo prvku zoznamu. Po zadaní vstupu je nový prvok pridaný na koniec zoznamu a následne vypíše celý aktuálny zoznam a znova ponúkne používateľovi zadať ďalší prvok. Program končí ak používateľ na vstupe zadá hodnotu -1.
Priebeh programu môže vyzerať nasledovne:
---
Zadajte hodnotu prvku: 1
Aktuálny zoznam: 1
---
Zadajte hodnotu prvku: 85
Aktuálny zoznam: 1, 85
---
Zadajte hodnotu prvku: 423
Aktuálny zoznam: 1, 85, 423
---
Zadajte hodnotu prvku: -1
#include <stdio.h>
#include <stdlib.h>
// Štruktúra pre uzol zreťazeného zoznamu
typedef struct Node {
int value;
struct Node *next;
} Node;
// Funkcia na vytvorenie nového uzla
Node* createNode(int value) {
Node* newNode = (Node*)malloc(sizeof(Node));
if (newNode == NULL) {
printf("Nepodarilo sa alokovať pamäť pre nový uzol.\n");
exit(1);
}
newNode->value = value;
newNode->next = NULL;
return newNode;
}
// Funkcia na pripojenie uzla na koniec zoznamu
void appendNode(Node** head, int value) {
Node* newNode = createNode(value);
if (*head == NULL) {
// Ak je zoznam prázdny, nový uzol sa stane hlavou
*head = newNode;
} else {
// Inak nájdeme posledný uzol a pripojíme nový uzol
Node* current = *head;
while (current->next != NULL) {
current = current->next;
}
current->next = newNode;
}
}
// Funkcia na výpis zoznamu
void printList(Node* head) {
Node* current = head;
if (current == NULL) {
printf("Zoznam je prázdny.\n");
return;
}
while (current != NULL) {
printf("%d", current->value);
if (current->next != NULL) {
printf(", ");
}
current = current->next;
}
printf("\n");
}
// Funkcia na uvoľnenie pamäte zoznamu
void freeList(Node* head) {
Node* current = head;
while (current != NULL) {
Node* temp = current;
current = current->next;
free(temp);
}
}
int main() {
Node* head = NULL; // Hlava zoznamu
int input;
while (1) {
printf("\nZadajte hodnotu prvku (-1 pre ukončenie): ");
scanf("%d", &input);
if (input == -1) {
break;
}
if (input < 0) {
printf("Zadajte iba kladné čísla alebo -1 pre ukončenie.\n");
continue;
}
// Pridanie nového prvku do zoznamu
appendNode(&head, input);
// Výpis aktuálneho zoznamu
printf("Aktuálny zoznam: ");
printList(head);
}
// Uvoľnenie pamäte
freeList(head);
printf("Pamäť bola uvoľnená. Program ukončený.\n");
return 0;
}