Department of Engineering

Next: Bibliography Up: Sample answers to exercises Previous: Exercises 2   Contents

## Exercises 3

• ```#include <stdio.h>
#include <stdlib.h>
#include <math.h>

/* This version of the primes program takes an optional
argument from the command line. Because it uses sqrt()
it needs the maths library.
*/

#define PRIME 1     /* Create aliases for 0 and 1 */
#define NONPRIME 0
#define DEFAULT_RANGE 1000
int maxprime;
int *numbers;
int range;

void usage(void){
printf("usage: prime [max]\n");
}

/* Set all elements which represent multiples of num to NONPRIME */
void mark_multiples(int num){
int multiple = num;
while (multiple+num <= range){
multiple = multiple+num;
numbers[multiple]= NONPRIME;
};
}

/* find the next prime in the range after `num' */
int get_next_prime(int num){
break;
}
}

main(int argc, char *argv[]){
int i;
int next_prime;

/* If more than 1 arg has been given , flag an error */
if (argc > 2){
usage();
exit(1);
}

/* If one arg has been given, try to read it as an integer
(sscanf returns the number of successfully scanned items)
*/
if (argc == 2){
if (sscanf(argv[1],"%d",&range) != 1)
range = DEFAULT_RANGE;
}
else
range = DEFAULT_RANGE;

maxprime = sqrt (range);

/* Instead of a fixed size array, malloc some space */
numbers = (int*) malloc( (range+1)* sizeof (int));

/* Set all the elements to PRIME.*/
for (i=0;i<range;i++)
numbers[i]= PRIME;

/* 0 and 1 aren't prime, so set numbers[0] and numbers[1] to false */
numbers[0] = NONPRIME;
numbers[1] = NONPRIME;

next_prime = 2;
do{
mark_multiples(next_prime);
next_prime = get_next_prime(next_prime);
} while(next_prime <= maxprime);

/* Print out the indices of elements which are still set to PRIME */
for (i=0;i<range;i++)
if (numbers[i]== PRIME)
printf("%d\n",i);

exit(0);
}
```
• ```#include <stdio.h>
#include <stdlib.h>
#define NUMBERCOUNT 10 /* the number of numbers */
int main()
{
/* Read 10 numbers from a file called 'data' */
int numbers[NUMBERCOUNT];
FILE *fp;
int i, return_value;
float total;
char line[100];

fp = fopen("data","r");
if (fp == NULL){
fprintf(stderr,"Cannot open 'data' for reading. Bye.\n");
exit(1);
}
/* Read the numbers in */
for(i=0;i<NUMBERCOUNT;i++){
if (fgets(line,100,fp) == NULL){
fprintf(stderr,"End of file reached too early. Bye.\n");
exit(1);
}

return_value = sscanf(line,"%d", numbers+i);
if (return_value !=1){
fprintf(stderr,"Cannot parse line %d of 'data'. Bye.\n",i+1);
exit(1);
}
}
fclose(fp);

/* Now calculate the total */
total=0.0;
for(i=0;i<NUMBERCOUNT;i++){
total=total+numbers[i];
}
printf("The total is %.3f. The average is %.3f\n",
total,total/NUMBERCOUNT);
}
```
• ```#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define UIDCOUNT 10
#define MAXUIDLENGTH 20

main()
{
/* Sort the first 10 uids in the password file */
char uids[UIDCOUNT][MAXUIDLENGTH];
char *cptr;
FILE *fp;
int i, return_value;
float total;
char line[100];

fp = fopen("/etc/passwd","r");
if (fp == NULL){
fprintf(stderr,"Cannot open '/etc/passwd' for reading. Bye.\n");
exit(1);
}

/* Read each of the first ten lines into the 'line' array.
Replace the first ':' by a '\0'. Copy the resulting
truncated string into the uids array
*/
for(i=0;i<UIDCOUNT;i++){
if (fgets(line,100,fp) == NULL){
fprintf(stderr,"End of file reached too early. Bye.\n");
exit(1);
}

cptr = strchr(line,':');
if (cptr == NULL){
fprintf(stderr,"Strange line in '/etc/passwd'. Bye.\n");
exit(1);
}

*cptr = '\0';
strncpy(uids[i],line,MAXUIDLENGTH);
}

/* See the qsort man page for an explanation of the following.
Note that strcmp doesn't precisely match the man page's
requirements, so you may get a warning message on compiling
*/
qsort((void*) uids, (size_t) UIDCOUNT, MAXUIDLENGTH, strcmp);

/* Print the sorted list */
for(i=0;i<UIDCOUNT;i++){
printf("%s\n", uids[i]);
}
}
```
• ```#include <stdio.h>
#include <stdlib.h>
#define TABLE_SIZE 50
#define MAX_STR_LEN 64
#define EMPTY  (-1)

typedef struct _entry {
int value;
struct _entry *next;
char str[20];
} Entry;

char str[MAX_STR_LEN];

/* Create an array of elements of type Entry */
Entry *table[TABLE_SIZE];

int process(char *str){
int value = 1;
while (*str){
value = value * (*str);
str++;
}
return value;
}

char * get_string(char str[])
{
printf("Input a string\n");
return gets(str);
}

int hashfn(char *str){
int total = 0;
int i;
while (i = *str++)
total += i;
}

void set_table_values(void){
/* set all the entries in the table to NULL
*/
int i;
for (i =0;i<TABLE_SIZE;i++)
table[i] = NULL;
}

void set_entry(Entry *entry, char *str){
strcpy(entry->str,str);
entry->value = process(str);
}

Entry *create_an_entry(void){
Entry *entry;
entry = (Entry*) malloc(sizeof (Entry));
return entry;
}

main(){
int bucket;
int value;
set_table_values();

/* Use get_string repeatedly. For each string:-
use the hash function to find the string's entry
in the table.
*/
while(get_string(str)){
if (! strcmp(str,"end")){
printf("Program ended\n");
exit(0);
}

bucket = hashfn(str);
value = find_entry(&(table[bucket]), str);
printf("Value of <%s> is %d\n",str,value);
}
}
```

Tim Love 2010-04-27