Reputation:
I have been working my way through Kochan's "Programming in C" 3rd Edition on my own to get ready for grad school next year, and I am stuck for the first time. I am a chapter away from pointers, yet the exercise at the end of this most recent chapter on character strings has a problem that my own research seems to indicate can only be solved by using pointers.
The question has to do with a data structure entry
:
struct entry {
char word[15];
char definition[50];
};
We create an array of entries:
struct entry dictionary[10] =
{{"aardvark", "a burrowing African mammal"},
{"abyss", "a bottomless pit"},
{"addle", "to become confused"},
{"aerie", "a high nest"},
{"ajar", "partially opened"},
{"acumen", "mentally sharp; keen"},
{"affix", "to append; attach"},
{"agar", "a jelly made from seaweed"},
{"ahoy", "a nautical call of greeting"},
{"aigrette", "an ornamental cluster of feathers"}};
The prompt reads: "Write a function called dictionary_sort
that sorts a dictionary, as defined [above], into alphabetical order."
I know there are subtleties to structures and arrays in relation to functions and how functions can take them as arguments or give them back as returned values. The only way that seemed to make sense to me was returning a struct, or specifically an array of structs, but I do not think I applying it correctly here:
struct entry dictionary_sort(struct entry dictionary)
In total, my current version of the program is as follows:
#include <stdio.h>
#include <stdbool.h>
struct entry {
char word[15];
char definition[50];
};
// Function to compare two character strings
int compare_strings(const char s1[], const char s2[])
{
int i = 0, answer;
while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
i++;
if (s1[i] < s2[i])
answer = -1; // s1 < s2
else if (s1[i] == s2[i])
answer = 0; // s1 == s2
else
answer = 1; // s1 > s2
return answer;
}
// Function to sort a dictionary structure
struct entry dictionary_sort(struct entry dictionary[])
{
int dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);
int i, j, minimum;
struct entry temp;
for (i = 0; i < dictionary_length; i++) {
minimum = i;
for (j = i + 1; j < dictionary_length; j++) {
if (compare_strings(dictionary[j].word,
dictionary[minimum].definition) == -1)
minimum = j;
}
temp = dictionary[minimum];
dictionary[minimum] = dictionary[i];
dictionary[i] = dictionary[minimum];
}
return dictionary;
}
int main(void)
{
struct entry dictionary[10] =
{{"aardvark", "a burrowing African mammal"},
{"abyss", "a bottomless pit"},
{"addle", "to become confused"},
{"aerie", "a high nest"},
{"ajar", "partially opened"},
{"acumen", "mentally sharp; keen"},
{"affix", "to append; attach"},
{"agar", "a jelly made from seaweed"},
{"ahoy", "a nautical call of greeting"},
{"aigrette", "an ornamental cluster of feathers"}};
int i, dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);
dictionary = dictionary_sort(dictionary);
for (i = 0; i < dictionary_length; i++)
printf("%s - %s.\n", dictionary[i].word, dictionary[i].definition);
return 0;
}
The string comparison function behaves as expected since it is only returning an integer. I am really at a loss as to how to have the desired functionality without knowledge of pointers. There are enough examples with pointers to look up, but I am curious what fundamental principle I am missing here because I feel as though everything else in the book has come very naturally to me.
Thank you in advance!
Upvotes: 0
Views: 2586
Reputation:
While not perfect and still requiring the explicit definition of pointers, this answer is within the scope of the problem and the book by not just calling libraries.
#include <stdio.h>
#include <stdbool.h>
struct entry {
char word[15];
char definition[50];
};
// Function to compare two character strings
int compare_strings(const char s1[], const char s2[])
{
int i = 0, answer;
while (s1[i] == s2[i] && s1[i] != '\0' && s2[i] != '\0')
i++;
if (s1[i] < s2[i])
answer = -1; // s1 < s2
else if (s1[i] == s2[i])
answer = 0; // s1 == s2
else
answer = 1; // s1 > s2
return answer;
}
// Function to sort a dictionary structure
void dictionary_sort(struct entry *dictionary, int dictionary_length)
{
int i, j, minimum;
struct entry temp;
for (i = 0; i < dictionary_length - 1; i++) {
minimum = i;
for (j = i + 1; j < dictionary_length; j++) {
if (compare_strings(dictionary[j].word,
dictionary[minimum].word) == -1)
minimum = j;
}
temp = dictionary[minimum];
dictionary[minimum] = dictionary[i];
dictionary[i] = temp;
}
}
// Prints the dictionary in its current state
void print_dictionary(struct entry *dictionary, int dictionary_length)
{
int i;
for (i = 0; i < dictionary_length; i++) {
printf("%s - %s.\n", dictionary[i].word, dictionary[i].definition);
}
}
// Demostrates the dictionary_sort function
int main(void)
{
struct entry dictionary[10] =
{{"aardvark", "a burrowing African mammal"},
{"abyss", "a bottomless pit"},
{"addle", "to become confused"},
{"aerie", "a high nest"},
{"ajar", "partially opened"},
{"acumen", "mentally sharp; keen"},
{"affix", "to append; attach"},
{"agar", "a jelly made from seaweed"},
{"ahoy", "a nautical call of greeting"},
{"aigrette", "an ornamental cluster of feathers"}};
int i, dictionary_length = sizeof(dictionary) / sizeof(dictionary[0]);
print_dictionary(&dictionary, dictionary_length);
printf("\nSorting...\n\n");
dictionary_sort(&dictionary, dictionary_length);
print_dictionary(&dictionary, dictionary_length);
printf("\n");
return 0;
}
Upvotes: 1
Reputation:
You do not have to return anything at all, you don't even need explicit pointers, none of that. Sort in-place, and don't reinvent the wheel: use strcmp()
and qsort()
(live demo here):
struct entry dictionary[] = {
{ "def", "second entry" },
{ "abc", "first entry" },
{ "ghi", "third entry" },
{ "mno", "fifth entry" },
{ "jkl", "fourth entry" }
};
int compare_entry(const void *l, const void *r)
{
const struct entry *ll = l;
const struct entry *rr = r;
return strcmp(ll->word, rr->word);
}
#define COUNT(x) (sizeof(x) / sizeof(x[0]))
qsort(dictionary, COUNT(dictionary), sizeof(dictionary[0]), compare_entry);
Upvotes: 4
Reputation: 3663
A statement like "Returning an array of structs without pointers in C"
is a paradox in C because the only way to pass or return an array in C is through pointers.Even though it may seem that in something like char *foo(char arr_demo[]){}
an array is being passed, essentially it's a pointer being passed as it reduces to char *foo(char *arr_demo){}
.
Upvotes: 0
Reputation: 74078
When you declare a function parameter with []
, you already use pointers. The function definition
int compare_strings(const char s1[], const char s2[])
is functionally the same as
int compare_strings(const char *s1, const char *s2)
Same with struct entry dictionary_sort(struct entry dictionary[])
.
Since you get a pointer to struct entry
as parameter dictionary
, return dictionary
returns a pointer to struct entry
as well.
And all changes you make to dictionary
are already visible outside, because you modify the array itself and not some local array.
Upvotes: 0