Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
master-embedded-systems
c-exercise-solutions public
Commits
58a34fc5
Commit
58a34fc5
authored
Sep 04, 2017
by
Dominik Widhalm
Browse files
Added example solutions for task 6.14
parent
36723b6f
Changes
2
Hide whitespace changes
Inline
Side-by-side
ch_6/task_14/main.c
0 → 100644
View file @
58a34fc5
/******************************************************************************
* C PROGRAMMING *
* BASIC EXERCISES - EXAMPLE SOLUTIONS *
* *
* Task_6.14: *
* Author: Dominik Widhalm *
* Email: dominik.widhalm@technikum-wien.at *
* Date: 2017-09-04 *
* *
******************************************************************************/
/***** INCLUDES ***************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/***** MACROS *****************************************************************/
// Maximum length of strings
#define STRING_MAX 80
/***** TYPEDEFS ***************************************************************/
/* Enumeration type for function return values */
typedef
enum
{
SUCCESS
,
FAILED
}
retval_t
;
/* Structure for a character (list) element */
typedef
struct
symbol
{
/* Character to be stored */
char
character
;
/* Count of this symbol */
int
count
;
/* Pointer to the next element */
struct
symbol
*
next
;
}
symbol_t
;
/***** FUNCTION PROTOTYPES ****************************************************/
symbol_t
*
symbol_new
(
char
character
);
symbol_t
*
symbol_find
(
symbol_t
*
head
,
char
character
);
void
symbol_print
(
symbol_t
*
head
);
retval_t
string_process
(
symbol_t
**
head
,
char
*
string
);
void
string_sort
(
symbol_t
**
head
);
void
string_print_stats
(
symbol_t
*
head
);
/***** LOCAL FUNCTIONS ********************************************************/
/******************************************************************************
* symbol_new *
* @brief Function to create a new symbol element. *
* *
* This function creates a new symbol element and returns its address. *
* *
* @param character Character of the new symbol *
* @return Pointer to the new symbol *
******************************************************************************/
symbol_t
*
symbol_new
(
char
character
)
{
/* Allocate memory for the new symbol */
symbol_t
*
new
=
(
symbol_t
*
)
malloc
(
sizeof
(
symbol_t
));
/* Check if malloc was successful */
if
(
new
==
NULL
)
{
/* Memory could not be allocated */
return
NULL
;
}
/* Write given character to new element */
new
->
character
=
character
;
/* The default count at moment of creation is 1 */
new
->
count
=
1
;
/* Initially set its pointer to NULL */
new
->
next
=
NULL
;
/* Return the address of the new element */
return
new
;
}
/******************************************************************************
* symbol_find *
* @brief Function to search for a symbol in the current list. *
* *
* This function searches the current list for the availability of a *
* given character. If an element with this character is found the *
* address of this element is returned; otherwise NULL is returned. *
* *
* @param head Pointer to the head of the list *
* @param character Character to be searched for *
* @return Address of the element found; or NULL *
******************************************************************************/
symbol_t
*
symbol_find
(
symbol_t
*
head
,
char
character
)
{
/* Temporary pointer to traverse the list */
symbol_t
*
curr
=
head
;
/* Iterate over the list */
while
(
curr
!=
NULL
)
{
/* Check if current element contains given characer */
if
(
curr
->
character
==
character
)
{
/* Current element contains this character */
return
curr
;
}
/* Go to the next element */
curr
=
curr
->
next
;
}
/* If this point is reached no element with the character was found */
return
NULL
;
}
/******************************************************************************
* symbol_print *
* @brief Function to print the list elements recursively. *
* *
* This function prints the list elements recursively. *
* *
* @param head Pointer to the head of the list *
******************************************************************************/
void
symbol_print
(
symbol_t
*
head
)
{
/* Print the current element */
printf
(
"|--> '%c' | %3dd | 0x%02X -- %02d occurences
\n
"
,
head
->
character
,(
int
)
head
->
character
,(
int
)
head
->
character
,
head
->
count
);
/* Check if the end of the list has not been reached yet */
if
(
head
->
next
!=
NULL
)
{
/* Call this function recursively with next element */
symbol_print
(
head
->
next
);
}
/* A void function has nothing to return */
return
;
}
/******************************************************************************
* string_process *
* @brief Function to process a given string. *
* *
* This function iterates over a given string and counts the occurrences *
* of the different characters contained dynamically. In the resulting *
* list only the characters available in the string are available. The *
* resulting list is not ordered; the elements appear in the order as *
* the character appear in the string. *
* *
* @param head Pointer to pointer of the head of the list *
* @param string String to be processed *
* @retval SUCCESS Successfully processed the given string *
* @retval FAILED Could not process the given string *
******************************************************************************/
retval_t
string_process
(
symbol_t
**
head
,
char
*
string
)
{
/* Temporary pointer used to access certain list elements */
symbol_t
*
elem
=
NULL
;
/* Temporary pointer to traverse the list */
symbol_t
*
curr
=
NULL
;
/* Temporary character (used to fix letter case) */
char
temp
;
/* Iterate over the entire string */
while
(
*
string
!=
'\0'
)
{
/* Store the current character */
temp
=
*
string
;
/* Check if character is upper case letter */
if
((
temp
>=
'A'
)
&&
(
temp
<=
'Z'
))
{
/* Make character lower case */
temp
+=
'a'
-
'A'
;
}
/* Search for current character in list */
elem
=
symbol_find
(
*
head
,
temp
);
/* Check if character is already in list */
if
(
elem
==
NULL
)
{
/* Character is not yet in list ... create a new element */
elem
=
symbol_new
(
temp
);
/* Check if element was created successfully */
if
(
elem
==
NULL
)
{
/* Could not create element --- return FAILED */
return
FAILED
;
}
else
{
/* Check if current list is empty */
if
(
*
head
==
NULL
)
{
/* Add new element at the begin */
*
head
=
elem
;
}
else
{
/* Go to the end of the current list */
curr
=
*
head
;
while
(
curr
->
next
!=
NULL
)
{
/* Go to the next element */
curr
=
curr
->
next
;
}
/* Append new element to the list */
curr
->
next
=
elem
;
}
}
}
else
{
/* Character is already in list ... increase its count */
elem
->
count
++
;
}
/* Continue with the next character in string */
string
++
;
}
/* Sort the acquired list of symbols */
string_sort
(
head
);
/* String was successfully processed */
return
SUCCESS
;
}
/******************************************************************************
* string_sort *
* @brief Function to sort the current list in ascending order. *
* *
* This function sorts the current list in ascending order according to *
* the character contained, respectively the ASCII value of the *
* character contained. *
* *
* @param head Pointer to pointer of the head of the list *
******************************************************************************/
void
string_sort
(
symbol_t
**
head
)
{
/* Temporary variables */
int
swapped
;
// Remembers if there had been a swap or not
symbol_t
*
curr
=
*
head
;
// Pointer to current element
symbol_t
*
prev
;
// Pointer to previous element
symbol_t
*
temp
;
// Temporary helper pointer
/* Check if the list is long enough to be sorted */
if
((
curr
==
NULL
)
||
(
curr
->
next
==
NULL
))
{
/* List is not long enough for sorting */
return
;
}
/* Repeat sorting as long as there are swaps */
do
{
/* Reset swapped to 0 */
swapped
=
0
;
/* Reset curr & prev to head */
curr
=
*
head
;
prev
=
*
head
;
/* Iterate over the entire list */
while
(
curr
->
next
!=
NULL
)
{
/* Check if entries need to be swapped */
if
(
curr
->
character
>
curr
->
next
->
character
)
{
/* Check if current element is the head (first) element */
if
(
*
head
==
curr
)
{
/* Swap elements */
*
head
=
curr
->
next
;
curr
->
next
=
(
*
head
)
->
next
;
(
*
head
)
->
next
=
curr
;
/* Correct curr & prev pointer */
curr
=
prev
;
prev
=
*
head
;
}
else
{
/* Swap elements */
prev
->
next
=
curr
->
next
;
curr
->
next
=
curr
->
next
->
next
;
prev
->
next
->
next
=
curr
;
/* Correct curr & prev pointer */
temp
=
curr
;
curr
=
prev
;
prev
=
temp
;
}
/* Remember that there have been a swap */
swapped
=
1
;
/* Continue with next iteration over the entire loop */
break
;
/* When not checking the first element */
}
else
if
(
*
head
!=
curr
)
{
/* Increment previous pointer */
prev
=
prev
->
next
;
}
/* Continue with next element */
curr
=
curr
->
next
;
}
}
while
(
swapped
==
1
);
/* A void function has nothing to return */
return
;
}
/******************************************************************************
* string_print_stats *
* @brief Function to print the statistics of the given string. *
* *
* This function prints the occurring characters as well as their number *
* of occurrences (count) in the given string. *
* *
* @param head Pointer to pointer of the head of the list *
******************************************************************************/
void
string_print_stats
(
symbol_t
*
head
)
{
/* Check if there is a valid list of character */
if
(
head
==
NULL
)
{
/* There is no list */
printf
(
"
\n
The given list is empty!
\n\n
"
);
}
else
{
/* Print stats output header */
printf
(
"
\n
========== STRING STATISTICS ==========
\n
"
);
/* Print the elements recursively */
symbol_print
(
head
);
/* Print stats output footer */
printf
(
"=======================================
\n\n
"
);
}
/* A void function has nothing to return */
return
;
}
/***** MAIN ROUTINE ***********************************************************/
int
main
(
void
)
{
/*** Local Variables ***/
symbol_t
*
head
=
NULL
;
symbol_t
*
next
=
NULL
;
char
string
[
STRING_MAX
];
/* Ask the user to enter a string */
printf
(
"Please enter a string:
\n
"
);
/* Read in the user's input */
fgets
(
string
,
STRING_MAX
,
stdin
);
/* Remove trailing newline */
strtok
(
string
,
"
\n
"
);
/* (Try to) process the string */
if
(
string_process
(
&
head
,
string
)
==
SUCCESS
)
{
/* Print the string statistics */
string_print_stats
(
head
);
}
else
{
/* Could not process the given string */
printf
(
"
\n
The given string could not be processed!
\n\n
"
);
}
/* Release the allocated memory (use pointer "next" as helper) */
while
(
head
!=
NULL
)
{
/* Save pointer to current element */
next
=
head
;
/* Set head to the next element */
head
=
next
->
next
;
/* Free memory of current element */
free
(
next
);
}
/* Notify the user about the termination of the program */
printf
(
"The program will now be terminated...
\n
"
);
return
0
;
/* Return with Success (0) */
}
/******************************************************************************/
ch_6/task_14/makefile
0 → 100644
View file @
58a34fc5
# Get the current path(s) (relevant directory on last position)
TASKPATH
:=
$(
dir
$(
abspath
$(
lastword
$(MAKEFILE_LIST)
)))
CHPATH
:=
$(
dir
$
(
TASKPATH:%/
=
%
))
# Variables for text substitution
empty
:=
slash
:=
/
space
:=
$(empty)
$(empty)
task
:=
task_
ch
:=
ch_
# Get TASK number
TASK
:=
$(
subst
$(slash)
,
$(space)
,
$(TASKPATH)
)
TASK
:=
$(
lastword
$(TASK)
)
TASK
:=
$(
subst
$(task)
,
$(empty)
,
$(TASK)
)
# Get CH number
CH
:=
$(
subst
$(slash)
,
$(space)
,
$(CHPATH)
)
CH
:=
$(
lastword
$(CH)
)
CH
:=
$(
subst
$(ch)
,
$(empty)
,
$(CH)
)
# Specify SRD directory
SRCDIR
=
.
# Call superior makefile
include
../../makefile
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment