1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
|
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define max(a,b) (a)>(b)?(a):(b)
#define min(a,b) (b)>(a)?(a):(b)
// Rule of thumb: Keep structured TYPES out of functions.
typedef struct
{
int nummer;
char namn[100];
float pris;
float volym;
char typ[100];
char stil[100];
char forpackning[20];
char land[20];
char producent[50];
float alkoholhalt;
}
vara;
// A utility function to fix a design flaw with strncpy()
char *strncpy0(char *dest, const char *src, size_t count)
{
dest[count-1] = '\0';
return strncpy(dest, src, count-1);
}
// Write a function that does your decoding
// Don't forget to check for errors!
// s will be modified.
bool string_to_vara(char *s, vara* v)
{
#define ssizeof(type, member) sizeof(((type*)0)->member)
char *tok;
if (!(tok = strtok(s, ","))) return false; v->nummer = atoi(tok);
if (!(tok = strtok(NULL, ","))) return false; strncpy0(v->namn, tok, ssizeof(vara,namn));
if (!(tok = strtok(NULL, ","))) return false; v->pris = atof(tok);
if (!(tok = strtok(NULL, ","))) return false; v->volym = atof(tok);
if (!(tok = strtok(NULL, ","))) return false; strncpy0(v->typ, tok, ssizeof(vara,typ));
if (!(tok = strtok(NULL, ","))) return false; strncpy0(v->stil, tok, ssizeof(vara,stil));
if (!(tok = strtok(NULL, ","))) return false; strncpy0(v->forpackning, tok, ssizeof(vara,forpackning));
if (!(tok = strtok(NULL, ","))) return false; strncpy0(v->land, tok, ssizeof(vara,land));
if (!(tok = strtok(NULL, ","))) return false; strncpy0(v->producent, tok, ssizeof(vara,producent));
if (!(tok = strtok(NULL, ","))) return false; v->alkoholhalt = atof(tok);
return true;
#undef ssizeof
}
// Write a function to compare two items
// Returns
// • -1 : a < b
// • 0 : a == b
// • 1 : a > b
int jamfora_nummer(vara *a, vara *b)
{
return (a->nummer < b->nummer) ? -1 : (a->nummer > b->nummer);
}
int jamfora_namn(vara *a, vara *b)
{
return strcmp(a->namn, b->namn);
}
// Now we need functions useful with qsort()
int qsort_jamfora_nummer(const void *a, const void *b)
{
return jamfora_nummer((vara*)a, (vara*)b);
}
int qsort_jamfora_namn(const void *a, const void *b)
{
return jamfora_namn((vara*)a, (vara*)b);
}
// Main program should terminate with a value in 0..127.
// Zero is success. Anything else is error.
// Do not use negative numbers.
// Also, try not to exit().
// Structure your program so that it returns from main().
int main()
{
// This is the array of items. It is the most important object here!
const unsigned MAX_NITEMS = 100; // Specify a maximum size for your array
vara items[MAX_NITEMS];
unsigned nitems = 0; // Keep track of the USED part of your array
// This is your temporary buffer and file pointer.
// They are needed to read the file.
char envara[512];
FILE *fp;
if ((fp = fopen("varor.csv", "r")) == NULL)
{
fprintf(stderr, "Filen varor.csv gick inte att öppna\n");
return 1;
}
// Read the list of items, up to MAX_NITEMS of them.
while (nitems < MAX_NITEMS && fgets(envara, sizeof(envara), fp))
{
// If the input line is too long, we cannot continue properly.
// Handle it here.
char* p = strchr(envara, '\n');
if (!p)
{
fprintf(stderr, "En inmatningsrad är för lång\n");
return 1;
}
*p = '\0';
// Attempt to decode the record and add it to the list of items.
if (!string_to_vara(envara, items+nitems)) break;
nitems += 1;
}
// We are done with the file. Close it now.
fclose(fp);
// Sort the items by number, name.
// (Pay attention to the order in which this is done: first name, then number!)
qsort(items, nitems, sizeof(vara), qsort_jamfora_namn);
qsort(items, nitems, sizeof(vara), qsort_jamfora_nummer);
// Print the sorted list of items.
for (int i = 0; i < nitems; i++)
printf("nummer: %d\n"
"namn: %s\n"
"pris: %f\n"
"volym: %f\n"
"typ: %s\n"
"stil: %s\n"
"forpackning: %s\n"
"land: %s\n"
"producent: %s\n"
"alkoholhalt: %f\n\n",
items[i].nummer,
items[i].namn,
items[i].pris,
items[i].volym,
items[i].typ,
items[i].stil,
items[i].forpackning,
items[i].land,
items[i].producent,
items[i].alkoholhalt
);
}
|