We have program which prints news.
Every news contains subject and body text. Also, we count how much was every
news read. Everytime a news get read, we add 1 to to the value "read".
Create functions which will print the top 5 of the news, how much in average
something gets read, and what's the difference between the top news and the
news in the middle.
Here is some nasty code, I've translated it from Croatian. Hope it makes
sense.
However, sorting looks pretty nasty and it's written badly. Any suggestions
in changing?
I am stuck with the deadline, only tomorrow is left for me for having fun
with this code.
Thanks in advance.
This is probably too late to help before your deadline; however, it
will hopefully be of help for your next assignment.
#include <stdlib.h>
#include <stdio.h>
#define MAXLENGTH 20
#define elementtype News
Why are you creating a synonym for the News type? What is the purpose
of using elementtype instead of News?
#define N 9 //number of news
Give constants meaningful names. "N" carries no meaning;
"NEWS_ITEM_COUNT" or "MAX_NEWS_ITEMS" would do a better job of
communicating that this constant stores the number of news items.
When you have to support large and complex programs, you come to
appreciate meaningful names.
typedef struct {
int ID;
char name[60];
char text[500]; //structure
int read;
} News;
typedef struct {
int last;
elementtype elements[MAXLENGTH];
} LIST;
This LIST type doesn't appear to be used anywhere in the code below.
What is its purpose?
void bubblesort(int *array){
You should pass the size of the array to bubblesort as a parameter
instead of relying on the global constant N. What if you had to sort
multiple arrays, each of different lengths? As written, your
bubblesort function is "tightly coupled" to your main program; it
cannot be easily reused. For a toy program like this, it's not that
much of an issue, but it's a bad habit to get into.
int i,j,k;
for (i=0; i<N; i++){
for (j=N-1; j>i; j--){
if (array[j-1]<array[j]){ //Bubble sort
k=array[j];
array[j]=array[j-1];
array[j-1]=k;
}
}
}
}
Note that the standard library already provides a sorting function,
qsort().
int main()
{
int n; // how many times we will allow analysis before
reading
int decision;
News new1 = {1,"heading 1.", "body 1"};
News new2 = {2,"heading 2.", "body 2"};
News new3 = {3,"Heading 3.", "body 3"};
News new4 = {4,"heading 4.", "body 4"};
News new5 = {5,"heading 5.", "body 5"};
News new6 = {6,"heading 6.", "body 6"};
News new7 = {7,"Heading 7.", "body 7"};
News new8 = {8,"Heading 8.", "body 8"};
News new9 = {9,"heading 9.", "body 9"};
Oy. This *screams* for an array:
News newsItems[NEWS_ITEM_COUNT] = {
{1, "heading 1.", "body 1"},
{2, "heading 2.", "body 2"},
...
};
printf("\t\t\tWelcome to the news sorting!\n\n\n\n");
for (n=0;n<15;n++){
Avoid magic numbers (numeric literals with no obvious meaning) in your
code. What is significant about 15? What does it represent?
printf("%d--> %s\n", new1.ID, new1.name,0);
You're passing more parameters to printf than you need to; the "0"
parameter isn't used.
Get rid of it.
printf("%d--> %s\n", new2.ID, new2.name,0);
printf("%d--> %s\n", new3.ID, new3.name,0);
printf("%d--> %s\n", new4.ID, new4.name,0);
printf("%d--> %s\n", new5.ID, new5.name,0);
printf("%d--> %s\n", new6.ID, new6.name,0);
printf("%d--> %s\n", new7.ID, new7.name,0);
printf("%d--> %s\n", new8.ID, new8.name,0);
printf("%d--> %s\n\n", new9.ID, new9.name,0);
Again, an array would make this a lot simpler:
int j;
for (j = 0; j < NEWS_ITEM_COUNT; j++)
printf("%d--> %s\n", newsItems[j].ID, newsItems[j].name);
printf("Enter number + ENTER for reading: ");
scanf("%d",&decision);
scanf() isn't recommended for interactive input, especially for
numeric input. It's better to use fgets() to read input as a string,
and then to convert it using strtol().
if (decision==1){
printf("---------------------------------------\n%s\n",
new1.text);
new1.read++;}
if (decision==2){
printf("---------------------------------------\n%s\n",
new2.text);
new2.read++;}
if (decision==3){
printf("---------------------------------------\n%s\n",
new3.text);
new3.read++;}
if (decision==4){
printf("---------------------------------------\n%s\n",
new4.text);
new4.read++;}
if (decision==5){
printf("---------------------------------------\n%s\n",
new5.text);
new5.read++;}
if (decision==6){
printf("---------------------------------------\n%s\n",
new6.text);
new6.read++;}
if (decision==7){
printf("---------------------------------------\n%s\n",
new7.text);
new7.read++;}
if (decision==8){
printf("---------------------------------------\n%s\n",
new8.text);
new8.read++;}
if (decision==9){
printf("---------------------------------------\n%s\n",
new9.text);
new9.read++;}
Again, this can be simplified greatly by using an array. You can
replace all those if statements with the following:
newsItems[decision].read++;
Remember that arrays in C are 0-origin (i.e., the array elements are
indexed from 0..8, not 1..9).
system("pause");
system("cls"); }
As for finding the 5 most-read articles, you have a number of options
here. One is to sort the newsItems array itself by modifying your
bubblesort function to sort an array of News instead of int. Or you
could use the standard library function qsort(), you just need to
write a comparison function:
int compareTimesRead(const void *item1, const void *item2)
{
News *newsItem1 = item1;
News *newsItem2 = item2;
if (newsItem1->read > newsItem2->read)
return 1;
else if (newsItem1->read < newsItem2->read)
return -1;
else
return 0;
}
and then in your main function, call qsort() as follows:
qsort((void *) newsItems,
NEWS_ITEM_COUNT,
sizeof *newsItems,
compareTimesRead);
You could avoid sorting entirely by simply walking the array once, and
keeping track of the most popular items as you go. The following code
only tracks the single most-popular item, but you should be able to
figure out how to extend it to store the N-most popular items (an
array might be helpful again here):
int mostPopularItemIndex = 0; /* start with the first element */
for (i = 1; i < NEWS_ITEM_COUNT; i++)
{
if (newsItem
.read > newsItem[mostPopularIndex].read)
{
mostPopularIndex = 0;
}
}
int array[N]={new1.read, new2.read, new3.read, new4.read, new5.read,
new6.read, new7.read, new8.read, new8.read};
bubblesort(array); // call bubblesort
Again, pass the size of the array as a parameter instead of relying on
the constant N.
//Most read news-------------------------------
if (new1.read==array[0]){
printf("Most read news is:\t%s", new1.name);}
if (new2.read==array[0]){
printf("Most read news is:\t%s", new2.name);}
if (new3.read==array[0]){
printf("Most read news is:\t%s", new3.name);}
if (new4.read==array[0]){
printf("Most read news is:\t%s", new4.name);}
if (new5.read==array[0]){
printf("Most read news is:\t%s", new5.name);}
if (new6.read==array[0]){
printf("Most read news is:\t%s", new5.name);}
if (new7.read==array[0]){
printf("Most read news is:\t%s", new7.name);}
if (new8.read==array[0]){
printf("Most read news is:\t%s", new8.name);}
if (new9.read==array[0]){
printf("Most read news is:\t%s", new9.name);}
//-------------------------------------------------
And again, storing the news items in an array makes all the if
statements above reduce to:
printf("Most read news is:\t%s\n",
newsItems[mostPopularIndex].name);
printf("\n");
//2. Second most read news-------------------------------
if (new1.read==array[1]){
printf("2. Most read news is:\t%s", new1.name);}
if (new2.read==array[1]){
printf("2. Most read news is:\t%s", new2.name);}
if (new3.read==array[1]){
printf("2. Most read news is:\t%s", new3.name);}
if (new4.read==array[1]){
printf("2. Most read news is:\t%s", new4.name);}
if (new5.read==array[1]){
printf("2. Most read news is:\t%s", new5.name);}
if (new6.read==array[1]){
printf("2. Most read news is:\t%s", new6.name);}
if (new7.read==array[1]){
printf("2. Most read news is:\t%s", new7.name);}
if (new8.read==array[1]){
printf("2. Most read news is:\t%s", new8.name);}
if (new9.read==array[1]){
printf("2. Most read news is:\t%s", new9.name);}
//-------------------------------------------------
printf("\n");
//3. most read news-------------------------------
if (new1.read==array[2]){
printf("3. Most read news is:\t%s", new1.name);}
if (new2.read==array[2]){
printf("3. Most read news is:\t%s", new2.name);}
if (new3.read==array[2]){
printf("3. Most read news is:\t%s", new3.name);}
if (new4.read==array[2]){
printf("3. Most read news is:\t%s", new4.name);}
if (new5.read==array[2]){
printf("3. Most read news is:\t%s", new5.name);}
if (new6.read==array[2]){
printf("3. Most read news is:\t%s", new6.name);}
if (new7.read==array[2]){
printf("3. Most read news is:\t%s", new7.name);}
if (new8.read==array[2]){
printf("3. Most read news is:\t%s", new8.name);}
if (new9.read==array[2]){
printf("3. Most read news is:\t%s", new9.name);}
//-------------------------------------------------
printf("\n\nDiffernce between the TOP news and one in the middle is:
%d - %d = %d", array[0], array[4], array[0] - array[4]);
printf("\n\n");
system("pause");
return 0;
}