This commit is contained in:
2025-04-09 10:22:44 +02:00
commit 96ff5392c8
330 changed files with 28300 additions and 0 deletions
+8
View File
@@ -0,0 +1,8 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="CPP_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>
+8
View File
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/exercise9.iml" filepath="$PROJECT_DIR$/.idea/exercise9.iml" />
</modules>
</component>
</project>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="" vcs="Git" />
</component>
</project>
+19
View File
@@ -0,0 +1,19 @@
# Hausübung 9 (3 Punkte)
**Ausgabe**: Donnerstag 23. Mai 2024, vormittags.
**Abgabe bis**: Montag 3. Juni 2024, Ende des Tages.
**Abgabe via**: git-Repository mit dem Namen **`exercise9`** auf unserem git-Server https://sgit.iue.tuwien.ac.at
Details zum Abgabeprozess via `git` finden Sie hier: https://sgit.iue.tuwien.ac.at/360050/git
# Aufgabenstellung
In dieser Hausübung werden folgende Themen erstmalig einfliessen:
- C: Nullterminierte Zeichenketten
- C: Lexikographischer Vergleich von Zeichenketten
- C: Kopieren von Zeichenketten
**Die genaue Beschreibung und Anforderungen finden Sie in [`main.ipynb`](main.ipynb) und im Quellcode.**
+217
View File
@@ -0,0 +1,217 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aufgabe 1: Ein eigenes kleines C-Programm (*count spaces in string*) (1 Punkt)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Erstellen Sie in [`task1.main.c`](task1.main.c) ein lauffähiges Ein-Dateien-Programm das folgende Struktur aufweist:\n",
"\n",
"- Einbinden benötigter Header-Dateien aus der Standardbibliothek, z.B.:\n",
"\t```c\n",
"\t#include <ctype.h> // isspace\n",
"\t#include <stdio.h> // printf\n",
"\t#include <stddef.h> // size_t\t\n",
"\t...\n",
"\t```\n",
"- Definition/Implementierung einer eigenen Funktion, z.B.:\n",
"\t```cpp\n",
"\tsize_t func(...) {\n",
"\t ...\n",
"\t}\n",
"\t``` \n",
"- Definition/Implementierung einer `main`-Funktion, die Ihre selbst geschriebene Funktion verwendet, z.B.:\n",
"\t```cpp\n",
"\tint main(){\n",
"\t ...\t\n",
"\t size_t res = func(...);\n",
"\t ...\t\n",
"\t return 0;\n",
"\t}\n",
"\t``` \n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"- Eine genaue Beschreibung und Anforderungen finden Sie in [`task1.main.c`](task1.main.c)\n",
"- Ihre Implementierung erfolgt ebenfalls in [`task1.main.c`](task1.main.c)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aufgabe 2: Vergleichen und Kopieren von nullterminierten Zeichenketten (1 Punkt)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "plaintext"
}
},
"source": [
"**Wichtig:** Sie duerfen fuer Aufgabe 2 **keine** Funktionalitaet aus der Header-Datei `<string.h>` (Standardbibliothek) verwenden. Hintergrund: die Funktionen, die Sie implementieren sind stark an Funktionen aus `<string.h>` angelehnt (`strcpy/strncpy` und `strcmp/strncmp`)."
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"Sie implementieren zwei Funktionen, die nullterminierte Zeichenketten lexikographisch vergleichen. Lexikographisch bedeutet hier: \n",
"- die Sequenzen werden Zeichen-für-Zeichen verglichen\n",
"- ein kleinerer Wert liegt lexikographisch vor einem grösseren Wert\n",
"- Bei der Kontrolle/Debuggen mittels Ausgabe in der Konsole ist die Zuordnung der Zeichen (`char`) mittels der [ASCII-Tabelle](https://en.wikipedia.org/wiki/ASCII#Character_set) zu beachten; es ergibt sich u.A. folgendes:\n",
"\t- Das Terminierungszeichen (`\\0`) kommt vor allen anderen Zeichen\n",
"\t- Zahlen kommen vor Buchstaben\n",
"\t- Grosse Buchstabe kommen vor kleinen Buchstaben\n",
"\t- usw.\n",
"\n",
"```c\n",
"// todo: implement\n",
"int task2_compare(const char* a, const char* b);\n",
"// todo: implement\n",
"int task2_compare_n(const char* a, const char* b, size_t count);\n",
"```\n",
"\n",
"Sie implementieren zwei weitere Funktionen, die nullterminierte Zeichenketten kopieren.\n",
"\n",
"```c\n",
"// todo: implement\n",
"char* task2_copy(char* dest, const char* src);\n",
"// todo: implement\n",
"char* task2_copy_n(char* dest, const char* src, size_t count);\n",
"```\n"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"- Die vorgegebenen Strukturen/Funktionen und eine genaue Beschreibung und Anforderungen finden Sie in [`task2.h`](task2.h)\n",
"- Ihre Implementierung erfolgt in [`task2.c`](task2.c)\n",
"- Die zugeordneten Tests finden Sie in [`task2.test.c`](task2.test.c) "
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Aufgabe 3: Analyse einer mehrzeiligen Zeichenkette (1 Punkt)\n",
"\n",
"Sie implementieren eine Funktionen, die eine nullterminierte mehrzeilige Zeichenkette analysiert:\n",
"- wieviele Zeilen gibt es?\n",
"- wieviele Wörter kommen vor?"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {
"vscode": {
"languageId": "c"
}
},
"source": [
"```c\n",
"struct StringStats {\n",
" unsigned int lines;\n",
" unsigned int words;\n",
"};\n",
"\n",
"// todo: implement\n",
"struct StringStats task3_stringstats(const char* str);\n",
"```"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"- Die vorgegebenen Deklaration und eine genaue Beschreibung und Anforderungen finden Sie in [`task3.h`](task3.h)\n",
"- Ihre Implementierung erfolgt in [`task3.c`](task3.c)\n",
"- Die zugeordneten Tests finden Sie in [`task3.test.c`](task3.test.c)"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"## Kompilieren/Testen\n",
"\n",
"So testen Sie Ihre Implementierung (direkter Aufruf von `gcc`):\n",
"\n",
"```shell\n",
"# prepare\n",
"mkdir build\n",
"# compile\n",
"gcc -g -std=c11 task1.main.c -o build/task1 -lm\n",
"gcc -g -Imodules -std=c11 task2.c task2.test.c -o build/task2 -lm\n",
"gcc -g -Imodules -std=c11 task3.c task3.test.c -o build/task3 -lm\n",
"\n",
"# run tests\n",
"./build/task1\n",
"./build/task2\n",
"./build/task3\n",
"```\n",
"\n",
"Alternativ (mittels CMake-Configuration):\n",
"\n",
"```shell\n",
"# prepare\n",
"cmake -S . -B build -D CMAKE_BUILD_TYPE=Debug\n",
"# compile\n",
"cmake --build build --config Debug --target task1\n",
"cmake --build build --config Debug --target task2\n",
"cmake --build build --config Debug --target task3\n",
"cmake --build build --config Debug # all\n",
"# run tests\n",
"ctest --test-dir build -C Debug -R task1 --verbose\n",
"ctest --test-dir build -C Debug -R task2 --verbose\n",
"ctest --test-dir build -C Debug -R task3 --verbose\n",
"ctest --test-dir build -C Debug # all\n",
"``` \n"
]
}
],
"metadata": {
"kernelspec": {
"display_name": ".venv",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.15"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
+18
View File
@@ -0,0 +1,18 @@
/// @file
/// @brief Task1: "single-file" executable C program
/// @todo Include C standard library headers as needed
/// @todo Implement a function 'count_spaces' according to the description below:
/// The function
/// - receives an pointer to a null-terminated charcater string,
/// - uses the function 'isspace' from <ctype.h> to count the number of spaces, and
/// - returns the result as an unsigned integer value
/// @todo Implement a 'main' function conducting the following tasks in this order:
/// - construct two local variables containing the following null-terminated string literals:
/// "How many spaces does this string contain?"
/// " How about this\n multiline string? "
/// - use your function 'count_spaces' to count the number of spaces in each of the string literals
/// - print both results to the console
int main() { return 0; }
+22
View File
@@ -0,0 +1,22 @@
/// @file
/// @brief Task2: function definitions
#include "task2.h" // task2_copy, task2_copy_n, task2_compare, task2_compare_n
#include <stddef.h> // size_t
/// @todo Include C standard library headers as needed, but note that
/// You are **not** allowed to use functionality from the header <string.h>
#include <stdlib.h> // NULL
/// @todo Implement function 'task2_compare' as declared and specified in task2.h
int task2_compare(const char* a, const char* b) { return 0; }
/// @todo Implement function 'task2_compare_n' as declared and specified in task2.h
int task2_compare_n(const char* a, const char* b, size_t count) { return 0; }
/// @todo Implement function 'task2_copy' as declared and specified in task2.h
char* task2_copy(char* dest, const char* src) { return NULL; }
/// @todo Implement function 'task2_copy_n' as declared and specified in task2.h
char* task2_copy_n(char* dest, const char* src, size_t count) { return NULL; }
+60
View File
@@ -0,0 +1,60 @@
/// @file
/// @brief Task2: Structure definitions and function declarations
#pragma once
#include <stddef.h> // size_t
/// @brief Compares two strings 'a' and 'b' lexicographically, byte-by-byte
/// until the first occurence of a null termination.
/// Note: The null termination character is part of the comparison
/// @param a Pointer to the first character range
/// @param b Pointer to the second character range
/// @return The function returns
/// - a negative value, if 'a' is lexicographically ordered before 'b',
/// - a positive value, if 'a' is lexicographically ordered after 'b',
/// - zero, if 'a' and 'b' are equal
/// @note This function requires:
/// - 'a' and 'b' point to null-terminated ranges
int task2_compare(const char* a, const char* b);
/// @brief Compares two strings 'a' and 'b' lexicographically, byte-by-byte until
/// - the occurence of a null termination, but at most
/// - up to the preset maximum 'count' of characters to be compare
/// Note: The null termination character is part of the comparison
/// @param a Pointer to the first character range
/// @param b Pointer to the second character range
/// @param count Maximum number of characters to be compared
/// @return The function returns
/// - a negative value, if 'a' is lexicographically ordered before 'b',
/// - a positive value, if 'a' is lexicographically ordered after 'b',
/// - zero, if 'a' and 'b' are equal
/// @note This function requires:
/// - 'a' and 'b' point to a null-terminated ranges
int task2_compare_n(const char* a, const char* b, size_t count);
/// @brief Copies a string until the first occurence of a null termination.
/// from a source 'src' to destination 'dest' location
/// @param dest Pointer to the first character of the destination range
/// @param src Pointer to the first character of the source range
/// @return Pointer to the first character of the destination range
/// @note This function requires:
/// - source and destination ranges do not overlap
/// - the source points to a null-terminated range
/// - the destination range fits the size of the source range (including a null termination character)
char* task2_copy(char* dest, const char* src);
/// @brief Copies a string from a source 'src' to destination 'dest' range:
/// - If the preset maximum 'count' of characters to be copied is reached before a null termination occurs in 'src' the
/// resulting destination range will not be null terminated, else
/// - the termination character is also placed in the destination range.
/// @param dest Pointer to the first character of the destination range
/// @param src Pointer to the first character of the source range
/// @param count Maximum number of characters to be copied
/// @return Pointer to the first character of the destination range
/// @note This function requires:
/// - source and destination ranges do not overlap
/// - the source points to a null-terminated range
/// - the destination range can fit 'count' characters
char* task2_copy_n(char* dest, const char* src, size_t count);
+126
View File
@@ -0,0 +1,126 @@
/// @file
/// @brief Task2: tests
#include "task2.h" // task2_copy, task2_copy_n, task2_compare, task2_compare_n
#include <assert.h> // assert
#include <stdio.h> // printf
int main() {
// testing 'task2_compare'
{
char a[] = "test";
char b[] = "test";
int res = task2_compare(a, b);
assert(res == 0); // fails if: equal strings do not return 0
}
{
char a[] = "test12";
char b[] = "test22";
int res = task2_compare(a, b);
assert(res < 0); // fails if: a before b does not return < 0
}
{
char a[] = "test31";
char b[] = "test22";
int res = task2_compare(a, b);
assert(res > 0); // fails if: b before a does not return > 0\n");
}
{
char a[] = "test1";
char b[] = "test12";
int res = task2_compare(a, b);
assert(res < 0); // fails if: strings equal up to end of a does not return < 0\n");
}
// testing 'task2_compare_n'
{
char a[] = "test1";
char b[] = "test12";
int res = task2_compare_n(a, b, 0);
assert(res == 0); // fails if: count == 0 does not return 0
}
{
char a[] = "test12";
char b[] = "test22";
int res = task2_compare_n(a, b, 4);
assert(res == 0); // fails if: string equal up to count does not return 0
}
{
char a[] = "test12";
char b[] = "test22";
int res = task2_compare_n(a, b, 5);
assert(res < 0); // fails if: a before b does not return < 0
}
{
char a[] = "test22";
char b[] = "test12";
int res = task2_compare_n(a, b, 5);
assert(res > 0); // fails if: b before a does not return > 0
}
{
char a[] = "test1\0XX";
char b[] = "test1\0YY";
int res = task2_compare_n(a, b, 8);
assert(res == 0); // fails if: characters after termination are considered in the comparison
}
// testing 'task2_copy'
{
const char src[] = "012345";
char dest[20] = "XXXXXXXXXXXXXXXXXXX";
char* res = task2_copy(dest, src);
assert(res == dest); // fails if: dest not returned from function
assert(dest[0] == '0'); // fails if: first char not present in dest
assert(dest[5] == '5'); // fails if: last char not present in dest
assert(dest[6] == '\0'); // fails if: dest not terminated correctly after copy
assert(dest[7] == 'X'); // fails if: manipulation of dest out of save range
}
// testing 'task2_copy_n'
char src[] = "0123456789";
src[6] = '\0';
{ // copying a range which terminates before count is reached
char dest[20] = "XXXXXXXXXXXXXXXXXXX";
int n = 10;
char* res = task2_copy_n(dest, src, n);
assert(res == dest); // fails if: dest not returned from function
int i = 0;
for (; i != 6; ++i)
assert(dest[i] == src[i]); // fails if: expected range not copied
assert(dest[i] == '\0'); // fails if: null termination not present
i = i + 1;
for (; i != 19; ++i)
assert(dest[i] == 'X'); // fails if: manipulation of dest out of save range
}
{ // copying where count is reached before source range terminates
char dest[20] = "XXXXXXXXXXXXXXXXXXX";
int n = 3;
char* res = task2_copy_n(dest, src, n);
assert(res == dest); // fails if: dest not returned from function
int i = 0;
for (; i != 2; ++i)
assert(dest[i] == src[i]); // fails if: expected range not copied
assert(dest[i] == src[i]); // fails if: null terminated
i = i + 1;
for (; i != 19; ++i)
assert(dest[i] == 'X'); // fails if: manipulation of dest out of save range
}
printf("task2.test.c: all asserts passed\n");
return 0;
}
+12
View File
@@ -0,0 +1,12 @@
/// @file
/// @brief Task3: function definitons
#include "task3.h" // struct StringStats, task3_stringstats
/// @todo Include C standard library headers as needed
/// @todo Implement this function according the the requirements specified in task3.h
struct StringStats task3_stringstats(const char* str) {
struct StringStats res = {0, 0};
return res;
}
+25
View File
@@ -0,0 +1,25 @@
/// @file
/// @brief Task3: structure and function declarations
#pragma once
/// @brief todo
struct StringStats {
unsigned int lines;
unsigned int words;
};
/// @brief Counts the number of lines and words in a null-terminated multiline string 'str':
/// Line:
/// - a line always ends with a newline ('\n') character
/// - 'str' is always terminated by a empty last line (terminated with the null character)
/// - this empty last line is not reflected in the number of lines (e.g. an empty string has zero lines)
/// Word:
/// - a word is here defined as each continuous sequence of non-whitespace characters
/// (e.g. also punctuation can be part of a word)
/// - whitespace characters are identified using 'isspace' from the 'ctype.h' standard library header
/// @param str Pointer to a null-terminated character range representing a multiline string:
/// - 'str' is always terminated by a empty last line
/// - 'str' is always null-terminated
/// @return Structure holding the number of lines and words counted in 'str'
struct StringStats task3_stringstats(const char* str);
+62
View File
@@ -0,0 +1,62 @@
/// @file
/// @brief Task3: tests
#include "task3.h" // struct StringStats, task3_stringstats
#include <assert.h> // assert
#include <stdio.h> // printf
int main() {
{ // testing 'task3_stringstats' (empty string)
const char str[] = "";
struct StringStats res = task3_stringstats(str);
assert(res.lines == 0);
assert(res.words == 0);
}
{ // testing 'task3_stringstats' (one line)
const char str[] = "this is one line\n";
struct StringStats res = task3_stringstats(str);
printf("stats: %u %u\n", res.lines, res.words);
assert(res.lines == 1);
assert(res.words == 4);
}
{ // testing 'task3_stringstats' (two lines)
const char str[] = "this is \ntwo lines.\n";
struct StringStats res = task3_stringstats(str);
printf("stats: %u %u\n", res.lines, res.words);
assert(res.lines == 2);
assert(res.words == 4);
}
{ // testing 'task3_stringstats' (two line leading spaces)
const char str[] = " this is \n two lines.\n";
struct StringStats res = task3_stringstats(str);
printf("stats: %u %u\n", res.lines, res.words);
assert(res.lines == 2);
assert(res.words == 4);
}
{ // testing 'task3_stringstats' (multiple lines)
const char str[] = "this is \nmore than\ntwo lines.\n";
struct StringStats res = task3_stringstats(str);
printf("stats: %u %u\n", res.lines, res.words);
assert(res.lines == 3);
assert(res.words == 6);
}
{ // testing 'task3_stringstats' (multiple lines, empty lines in between, leading spaces, trailing spaces)
const char str[] = " this is \n more than\n two lines \n including \n\n empty lines \n and spaces.\n";
// const char str[] = " \n\n ";
struct StringStats res = task3_stringstats(str);
printf("stats: %u %u\n", res.lines, res.words);
assert(res.lines == 7);
assert(res.words == 11);
}
printf("task3.test.c: all asserts passed\n");
return 0;
}