Programmeringsmetodik: Lösningar till tentamen 2010-12-11

Observera att detta är ett förslag på lösningar. Det finns andra lösningar som också är korrekta.

Testfiler

Testfiler finns med på tentan.

1. Uppgift för betyget 3 respektive G

Ladda ner: counters.c

// counters.c

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

struct Counter {
    int id;
    int value;
    struct Counter *next;
    struct Counter *previous;
};

struct Counter *sentinel = NULL;

void setup_sentinel() {
    sentinel = malloc(sizeof(struct Counter));
    sentinel->id = -1;
    sentinel->value = -1;
    sentinel->next = sentinel;
    sentinel->previous = sentinel;
}

struct Counter *find_counter(int id) {
    struct Counter *p = sentinel->next;
    while (p != sentinel) {
        if (p->id == id)
            return p;
        p = p->next;
    }
    return NULL;
}

int count_counters() {
    struct Counter *p = sentinel->next;
    int n = 0;

    while (p != sentinel) {
        ++n;
        p = p->next;
    }
    return n;
}

void print_counters() {
    struct Counter *p = sentinel->next;

    printf("Det finns %d räknare:\n", count_counters());
    while (p != sentinel) {
        printf("%d: %d\n", p->id, p->value);
        p = p->next;
    }
}

void create_counter(int id) {
    if (find_counter(id) != NULL){
        printf("Varning: Räknare %d fanns redan, så den skapades inte.\n", id);
    }
    else {
        struct Counter *p = malloc(sizeof(struct Counter));
        p->id = id;
        p->value = 0;
        p->next = sentinel;
        p->previous = sentinel->previous;
        sentinel->previous->next = p;
        sentinel->previous = p;
    }
}

void remove_counter(int id) {
    struct Counter *p;
    if ((p = find_counter(id)) == NULL){
        printf("Varning: Räknare %d fanns inte, så den kunde inte tas bort.\n", id);
    }
    else {
        p->previous->next = p->next;
        p->next->previous = p->previous;
        free(p);
    }
}

void increment_counter(int id) {
    struct Counter *p;
    if ((p = find_counter(id)) == NULL){
        printf("Varning: Räknare %d fanns inte, så den kunde inte ökas.\n", id);
    }
    else {
        p->value ++;
    }
}

int main(void) {
    char file_name[2000 + 1];
    FILE *fp;
    char command;
    int id;
    int c;

    setup_sentinel();

    printf("Ge filens namn: ");
    fgets(file_name, sizeof file_name, stdin);
    if (file_name[strlen(file_name) - 1] == '\n')
        file_name[strlen(file_name) - 1] = '\0';
    fp = fopen(file_name, "r");
    if (fp == NULL) {
        printf("Fel: Kunde inte öppna filen '%s'\n", file_name);
        exit(EXIT_FAILURE);
    }

    while (fscanf(fp, "%c %d", &command, &id) == 2) {
        // Skip the rest of the line
        while ((c = getc(fp)) != '\n' && c != EOF)
            ;

        if (id < 0)
            printf("Varning: Otillåtet räknarnummer (%d). Kommandot ignoreras.\n", id);
        else if (command == 'C')
            create_counter(id);
        else if (command == 'R')
            remove_counter(id);
        else if (command == 'I')
            increment_counter(id);
        else
            printf("Varning: Ett otillåtet kommando i textfilen har ignorerats.\n");
    }

    print_counters();

    return 0;
}

2. Uppgift för betyget 4 respektive VG

Ingen lösning än.

3. Uppgift för betyget 5

Ingen lösning än.


Thomas Padron-McCarthy (thomas.padron-mccarthy@oru.se), 11 december 2010