Find pset3 "\expected an exit code of 0, not 1" - c

all mighty community of CS50ers on StackOverflow!
I have coded the sort and search functions of pset3, find, but I just don't get why I get this message. It is as if in the while loop the first if were never executed.
Any hints?
#include <cs50.h>
bool search(int value, int values[], int n)
{
if (n < 1)
{
return false;
}
else
{
int start = 0, end = (n-1);
while (end >= start)
{
int median = (end - start) / 2;
if (median == value)
{
return true;
}
else if (values[median] < value)
{
start = values[median + 1];
}
else
{
end = values[median - 1];
}
}
return false;
}
}
void sort(int values[], int n)
{
int temp;
for (int i = 0; i < n; i++)
{
int smallest_index = i;
for (int j = i + 1; j < n; j++)
{
if (values[i] > values[j])
smallest_index = j;
}
temp = values[smallest_index];
values[smallest_index] = values[i];
values[i] = temp;
}
}
Click Here to See Error Message from Check50

Related

Segfault in Merge - Sort in C

I am trying to sort an array of structures of size 5500 using merge sort.
However, I am getting a segmentation fault pretty quickly because I am not allowed to use VLA. so I have to create 2 extra arrays of size 5500 each time I call merge-sort recursively.
I would appreciate a fix for my problem. I will provide my code here:
void merge(Student rightArr[], Student leftArr[], Student mergedArr[], int sizeOfRight, int sizeOfLeft) {
int rightArrIndex = 0;
int leftArrIndex = 0;
int mergedArrIndex = 0;
while (leftArrIndex < sizeOfLeft && rightArrIndex < sizeOfRight) {
char *ptrLeft, *ptrRight;
long gradeLeft = strtol(leftArr[leftArrIndex].grade, &ptrLeft, BASE_COUNT);
long gradeRight = strtol(rightArr[rightArrIndex].grade, &ptrRight, BASE_COUNT);
if (gradeLeft > gradeRight) {
mergedArr[mergedArrIndex] = rightArr[rightArrIndex];
rightArrIndex++;
} else {
mergedArr[mergedArrIndex] = leftArr[leftArrIndex];
leftArrIndex++;
}
mergedArrIndex++;
}
if (leftArrIndex == sizeOfLeft) {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = rightArr[rightArrIndex];
rightArr++;
}
} else {
for (int i = mergedArrIndex; i < (sizeOfLeft + sizeOfRight); i++) {
mergedArr[i] = leftArr[leftArrIndex];
leftArr++;
}
}
}
void mergeSort(Student studentsArray[], int amountOfStudents) {
if (amountOfStudents <= 1) {
return;
}
int leftSize = (amountOfStudents / 2);
int rightSize = (amountOfStudents - leftSize);
Student leftArr[5500], rightArr[5500];
for (int i = 0; i < leftSize; i++) {
leftArr[i] = studentsArray[i];
}
for (int i = 0; i < rightSize; i++) {
rightArr[i] = studentsArray[i + leftSize];
}
mergeSort(leftArr, leftSize);
mergeSort(rightArr, rightSize);
merge(rightArr, leftArr, studentsArray, rightSize, leftSize);
}
Ok, I think this should do what you want. It assumes that Student and BASE_COUNT have been defined:
#include <stdlib.h>
#include <stdio.h>
void merge(Student studentsArr[],
int leftSize, int rightSize,
Student scratchArr[])
{
Student *leftArr = studentsArr;
Student *rightArr = studentsArr + leftSize;
int leftIx = 0, rightIx = 0, mergeIx = 0, ix;
while (leftIx < leftSize && rightIx < rightSize) {
long gradeLeft = strtol(leftArr[leftIx].grade, NULL, BASE_COUNT);
long gradeRight = strtol(rightArr[rightIx].grade, NULL, BASE_COUNT);
if (gradeLeft <= gradeRight) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
else {
scratchArr[mergeIx++] = rightArr[rightIx++];
}
}
while (leftIx < leftSize) {
scratchArr[mergeIx++] = leftArr[leftIx++];
}
// Copy the merged values from scratchArr back to studentsArr.
// The remaining values from rightArr (if any) are already in
// their proper place at the end of studentsArr, so we stop
// copying when we reach that point.
for (ix = 0; ix < mergeIx; ix++) {
studentsArr[ix] = scratchArr[ix];
}
}
void mergeSortInternal(Student studentsArray[],
int amountOfStudents,
Student scratchArr[])
{
if (amountOfStudents <= 1) {
return;
}
int leftSize = amountOfStudents / 2;
int rightSize = amountOfStudents - leftSize;
mergeSortInternal(studentsArray, leftSize, scratchArr);
mergeSortInternal(studentsArray + leftSize, rightSize, scratchArr);
merge(studentsArray, leftSize, rightSize, scratchArr);
}
#define MAX_ARR_SIZE 5500
void mergeSort(Student studentsArray[], int amountOfStudents)
{
if (amountOfStudents <= 1) {
return;
}
if (amountOfStudents > MAX_ARR_SIZE) {
fprintf(stderr, "Array too large to sort.\n");
return;
}
Student scratchArr[MAX_ARR_SIZE];
mergeSortInternal(studentsArray, amountOfStudents, scratchArr);
}
The top-level sort function is mergeSort, defined as in the original post. It declares a single scratch array of size MAX_ARR_SIZE, defined as 5500. The top-level function is not itself recursive, so this scratch array is only allocated once.

School program tests not covering my code correctly and I'm not sure why

This might be inappropriate but I'm working on a school project in university and we use an automated test service called Web-Cat. When I upload my file (everything is correct as for the filename and method names etc.) the tests throw this at me:
hint: your code/tests do not correctly cover error: Cannot locate behavioral analysis output.
My code looks like this, I can't find any compile errors or anything that would cause such a problem.
#include <stdio.h>
double getPositiveAverage(double array[], int numItems)
{
double average = 0;
int numOfItems = 0;
for (int i = numItems-1; i >= 0; i--)
{
if (array[i] > 0)
{
average = average + array[i];
numOfItems++;
}
}
if (numOfItems == 0) {
return 0;
}
else {
return average / numOfItems;
}
}
int countRangeValues(double array[], int numItems, double count)
{
double countPlus = count + .5;
double countMinus = count - .5;
int counter = 0;
for (int i = numItems-1; i >= 0; i--)
{
if ((array[i] >= countMinus) && (array[i] < countPlus))
{
counter++;
}
}
return counter;
}
double getMaxAbsolute(double array[], int numItems)
{
double max = 0;
for (int i = numItems-1; i >= 0; i--)
{
if (array[i] == max * -1 && array[i] > 0)
{
max = array[i];
}
else if (array[i] < 0)
{
if (max < 0)
{
if ((array[i] * -1) > (max * -1))
{
max = array[i];
}
}
else
{
if ((array[i] * -1) > max)
{
max = array[i];
}
}
}
else
{
if (max < 0)
{
if ((array[i]) > (max * -1))
{
max = array[i];
}
}
else
{
if ((array[i]) > max)
{
max = array[i];
}
}
}
}
return max;
}
int countInverses(int array[], int numItems)
{
int negarray[numItems];
int negItems = 0;
int posarray[numItems];
int posItems = 0;
int counter = 0;
for (int i = numItems-1; i >= 0; i--)
{
if (array[i] < 0)
{
negarray[negItems] = array[i];
negItems++;
}
else if(array[i] > 0)
{
posarray[posItems] = array[i];
posItems++;
}
}
if (posItems == 0 || negItems == 0)
{
return 0;
}
else
{
if (posItems > negItems)
{
for (int i = posItems-1; i >= 0; i--)
{
for (int j = negItems-1; j >= 0; j--)
{
if ((negarray[j]*-1) == posarray[i] && negarray[j] != 0)
{
counter++;
negarray[j] = 0;
posarray[i] = 0;
}
}
}
}
}
return counter;
}
int getMaxCount(double array[], int numItems)
{
return countRangeValue(array, numItems, getMaxAbsolute(array, numItems));
}
If necessary, I can explain the purpose of all of these methods but the test also says "Your program failed before running any tests. Usually this is a compile problem or premature exit problem. Make sure your program compiles and runs before uploading." So I assume its syntax a compiling problem, I just don't know if anything I did would cause something like that.
Candidate problems:
Compilation error #fussel
// return countRangeValue(array, numItems, getMaxAbsolute(array, numItems));
return countRangeValues(array, numItems, getMaxAbsolute(array, numItems));
Missing main() #Bob__.
Variable length arrays are OK #Eric Postpischil in C99 and optionally in C11 yet do not attempt without insuring a positive array size.
int countInverses(int array[], int numItems) {
if (numItems <= 0) {
return 0;
}
int negarray[numItems];
....
Instead of if (posItems > negItems) { I'd expect if (posItems >= negItems) { or maybe even if (1), yet the goal of countInverses() lacks details for deep analysis.
countRangeValues(..., double count) is suspicious with double count. When count is a large value, countPlus == count and countMinus == count. The function always returns 0 as array[i] >= countMinus) && (array[i] < countPlus) is always false.
OP's getMaxAbsolute() looks too convoluted. Suggested alternative:
double getMaxAbsolute(const double array[], int numItems) {
double max = 0.0;
double amax = 0.0;
for (int i = numItems - 1; i >= 0; i--) {
double aelement = fabs(array[i]);
// If greater or the same, favor + over -
if (aelement > amax || (aelement == amax && array[i] > max)) {
max = array[i];
amax = aelement;
}
}
return max;
}

Possible mode error

I've made this program that computes the mean, the median and the mode from an array. Although I've tested with some examples, I found out there might be a case that I have forgotten as for many of the inputs I've tested it works but the testing program that my teacher is using gave me an error for a certain test, but I was not presented with its input. Maybe someone can have a look and see if I am making a mistake at the mode point of the code:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
scanf("%d", &n);
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
int value;
scanf("%d", &value);
array[i] = value;
}
//mean
double mean;
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
mean = sum / n;
printf("mean: %.2f\n", mean);
//median
float temp;
int j;
for (i = 0; i < n; i++)
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1, possibleMax = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
}
if (array[i] != val) {
val = array[i];
noOfRepetitions = 1;
}
if (noOfRepetitions == possibleMax) {
maxRepetitions = 1;
continue;
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
possibleMax = maxRepetitions;
}
}
if (maxRepetitions > 1) {
printf("mode: %d\n", valMax);
} else {
printf("mode: NONE\n");
}
return 0;
}
My idea for mode was because the numbers are sorted when just transverse it. If the next element is the same as the previous one, increase the noOfRepetitions. If the noOfRepetition is bigger than the maxRepetitions until now, replace with that. Also store the last maximum val needed if we have for example more than 2 numbers with the same number of repetitions.
EDIT: The mode of an array should return the number with the maximum number of occurrences in the array.If we have 2 or more number with the same number of maximum occurrences , there isn't a mode on that array.
I've discovered my mistake. I didn't think of the case when I have numbers with same maximum frequency and after that came one with lower frequency but still bigger than others. For example : 1 1 1 2 2 2 3 3 4 5 6.With my code , the result would have been 3 . I just needed to change the comparison of noOfRepetitions with oldMaxRepetition.
There seems to be no purpose for the variable possibleMax. You should just remove these lines:
if(noOfRepetitions==possibleMax){
maxRepetitions=1;
continue;
}
They cause maxRepetitions to be reset erroneously.
You could detect if the distribution is multimodal and print all mode values:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
int main(int argc, char *argv[]) {
int n, i;
if (scanf("%d", &n) != 1 || n <= 0)
return 1;
int *array = safeMalloc(n * sizeof(int));
for (i = 0; i < n; i++) {
if (scanf("%d", &array[i]) != 1)
return 1;
}
//mean
double sum = 0;
for (i = 0; i < n; i++) {
sum = sum + (double)array[i];
}
printf("mean: %.2f\n", sum / n);
//median
int j;
for (i = 0; i < n; i++) {
for (j = i + 1; j < n; j++) {
if (array[i] > array[j]) {
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
}
printf("median: %d\n", array[n / 2]);
//mode
int val = array[0], noOfRepetitions = 1, valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
} else {
val = array[i];
noOfRepetitions = 1;
}
}
if (maxRepetitions == 1) {
printf("mode: NONE\n");
} else {
printf("mode: %d", valMax);
val = array[0];
noOfRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
noOfRepetitions++;
} else {
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetition == maxRepetitions && val != valMax) {
printf(", %d", val);
}
printf("\n");
}
return 0;
}
Your code to search a mode seems too complicated. Compare this:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
if (++noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
}
else
{
val = array[i];
noOfRepetitions = 1;
}
}
It's probably the simplest code to do what you need, but it overwrites maxVal and maxRepetitions much too often.
The following version overwrites the two 'max' variables only once per each new maximum found – at the cost of duplicating some part of code:
//mode
int val = array[0], noOfRepetitions = 1,
valMax = array[0], maxRepetitions = 1;
for (i = 1; i < n; i++) {
if (array[i] == val) {
++noOfRepetitions;
}
else
{
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}
val = array[i];
noOfRepetitions = 1;
}
}
if (noOfRepetitions > maxRepetitions) {
valMax = val;
maxRepetitions = noOfRepetitions;
}

Comparing sorting methods in C

I have to compare these 3 sorting functions (bubble, insertion, and selection), in their worst, best, and the random possible way to sort an array (when talking about the idea of numbers of comparison).
I built and ran the program. The compiler is working, everything seems fine. The problem is that after the cmd window appears, nothing happens. The program is not returning anything (neither 0 (because of return 0) or writing sth in the file). How can I fix it?
#include <stdio.h>
#include <stdlib.h>
int b[11000];
int w[11000];
int r[11000];
int n;
int comp;
int attr;
FILE*f;
//CREAREA SIRURILOR
//best, worst, random
void sir(int n)
{ int i;
for(i=0; i<n; i++)
{
b[i] = i;
r[i] = rand() % n;
w[i] = n-i-1;
}
}
//INSERTION SORT
void insertion (int a[1000])
{
int j, i, index;
comp = 0;
attr = 0;
for (i = 0; i < n; i++)
{
index = a[i];
j = i;
attr+=1;
while ((j > 0) && (a[j-1] > index))
{ comp++;
a[j] = a[j-1];
j = j-1;
attr+=1;
}
while ((j > 0) || (a[j-1] > index))
{ comp++;
}
a[j] = index;
attr++;
}
fprintf(f,"\t%d\t", comp);
fprintf(f,"\t%d\t", attr);
fprintf(f,"\t%d\t", attr+comp);
}
//Selection Sort
void selection (int a[1000])
{
int j, i, min, temp;
comp = 0;
attr = 0;
for (i = 0; i < n-1; i++)
{
min = i;
for (j = i+1; j < n; j++){
comp++;
if (a[j] < a[min])
min = j;
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
attr+=3;
}
fprintf(f,"\t%d\t", comp);
fprintf(f,"\t%d\t", attr);
fprintf(f,"\t%d\t", attr+comp);
}
//Bubble Sort
void bubblesort (int array[2000])
{
int sorted;
int swap,d;
int c;
comp = 0;
attr = 0;
for (c = 0 ; c < ( n - 1 ); c++)
{
for (d = 0; d < n - c - 1; d++)
{
comp++;
if (array[d] > array[d + 1])
{
swap = array[d];
array[d] = array[d + 1];
array[d + 1] = swap;
attr += 3;
}
}
}
fprintf(f,"\t %d\t", comp);
fprintf(f,"\t %d\t", attr);
fprintf(f,"\t%d\t", attr+comp);
}
void InsertionSort()
{
insertion(b);
insertion(r);
insertion(w);
}
void SelectionSort()
{
selection(b);
selection(r);
selection(w);
}
void BubbleSort()
{
bubblesort(b);
bubblesort(r);
bubblesort(w);
}
int main ()
{
f = fopen("iesire.txt","w+");
if(f == NULL)
{
printf("Error!");
exit(-1);
}
fprintf(f,"\n Bubble Sort\t\n");
fprintf(f,"\tBest\t\t\t\t\t\tAverage\t\t\t\t\t\tWorst\t\t\n");
fprintf(f,"\tComparatii\t\tAtribuiri\t\tComp+Atr\t\tComparatii\t\tAtribuiri\t\tComp+Atr\t\tComparatii\t\tAtribuiri\t\tComp+Atr\n");
for (n = 100; n<=10000; n+=500)
{
sir(n);
BubbleSort();
fprintf(f,"\n");
}
fprintf(f,"\n\n Selection Sort\t\n");
fprintf(f,"\tBest\t\t\t\t\t\tAverage\t\t\t\t\t\tWorst\t\t\n");
fprintf(f,"\tComparatii\t\tAtribuiri\t\tComp+Atr\t\tComparatii\t\tAtribuiri\t\tComp+Atr\t\tComparatii\t\tAtribuiri\t\tComp+Atr\n");
for (n = 100; n<=10000; n+=500)
{
sir(n);
InsertionSort();
fprintf(f,"\n");
}
fprintf(f,"\n\n Insertion Sort\t\n");
fprintf(f,"\tBest\t\t\t\t\t\tAverage\t\t\t\t\t\tWorst\t\t\n");
fprintf(f,"\tComparatii\t\tAtribuiri\t\tComp+Atr\t\tComparatii\t\tAtribuiri\t\tComp+Atr\t\tComparatii\t\tAtribuiri\t\tComp+Atr\n");
for (n = 100; n<=10000; n+=500)
{
sir(n);
SelectionSort();
fprintf(f,"\n");
}
fclose(f);
printf(" Result: 'iesire.txt'.");
return 0;
}

Having issues with pointers

I'm fairly new to programming and i'm having problem with pointers. My code below works with the exception for that my counts doesn't follow with my article number when i sort it. I probably need pointers to get this working but I don't know how.
Can anyone help me?
void printMenu(void)
{
printf("\nMENU:\n");
printf("(D)isplay the menu\n");
printf("(G)enerate inventory\n");
printf("(P)rint inventory\n");
printf("(L)inear search article\n");
printf("(B)inary search article\n");
printf("(I)nsertion sort inventory\n");
printf("B(u)bble sort inventory\n");
printf("(M)erge sort inventory\n");
printf("(Q)uit program\n");
}
void generateInventory(article inventory[], int noOfArticles,
int minArticleNumber, int maxArticleNumber, int maxNoOfArticles)
{
int i, j;
int idCount[] =
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
for (i = 0; i < noOfArticles; i++)
{
inventory[i].id = rand() % (maxArticleNumber - minArticleNumber + 1) +
minArticleNumber;
idCount[inventory[i].id - 1] = idCount[inventory[i].id - 1] + 1;
for (j = 0; j <= i; ++j)
{
if (idCount[inventory[i].id - 1] > 1)
{
inventory[i].id = rand() % (maxArticleNumber + minArticleNumber);
}
}
inventory[i].counts = rand() % maxNoOfArticles;
}
}
void printInventory(const article inventory[], int noOfArticles)
{
int i;
printf("\nINVENTORY\n");
printf("%7s %8s\n", "Article", "Count");
for (i = 0; i < noOfArticles; i++)
{
printf("%7d %8d\n", inventory[i].id, inventory[i].counts);
}
}
int getArticleId()
{
int id;
printf("\nGive article id: ");
scanf("%d", &id);
return id;
}
void printSearchResult(const article inventory[], int index)
{
if (index == -1)
{
printf("\nArticle not found\n");
}
else
{
printf("\nArticle id: %d\n", inventory[index].id);
printf("Article counts: %d\n", inventory[index].counts);
}
}
int linearSearchInventory(const article inventory[], int noOfArticles, int id)
{
int i = 0;
int index = -1;
while (index == -1 && i < noOfArticles)
{
if (id == inventory[i].id)
{
index = i;
}
i++;
}
}
int binarySearchInventory(const article inventory[], int noOfArticles, int id)
{
int index = -1;
int left = 0;
int right = noOfArticles - 1;
int middle;
while (index == -1 && left <= right)
{
middle = (left + right) / 2;
if (id == inventory[middle].id)
{
index = middle;
}
else if (id < inventory[middle].id)
{
right = middle - 1;
}
else
{
left = middle + 1;
}
}
return index;
}
void insertionSortInventory(article inventory[], int noOfArticles)
{
int i, j;
int next;
for (i = 1; i < noOfArticles; i++)
{
next = inventory[i].id;
j = i - 1;
while (j >= 0 && next < inventory[j].id)
{
inventory[j + 1].id = inventory[j].id;
j = j - 1;
}
inventory[j + 1].id = next;
}
}
void bubbleSortInventory(article inventory[], int noOfArticles)
{
int c, d, t;
for (c = 0; c < (noOfArticles - 1); c++)
{
for (d = 0; d < noOfArticles - c - 1; d++)
{
if (inventory[d].id > inventory[d + 1].id)
{
t = inventory[d].id;
inventory[d].id = inventory[d + 1].id;
inventory[d + 1].id = t;
}
}
}
}
void mergeSortInventory(article inventory[], int noOfArticles)
{
int temp[noOfArticles / 2];
int nLeft, nRight;
int i, iLeft, iRight;
if (noOfArticles > 1)
{
nLeft = noOfArticles / 2;
nRight = (int) ceil((double) noOfArticles / 2);
mergeSortInventory(inventory, nLeft);
mergeSortInventory(&inventory[noOfArticles / 2], nRight);
for (i = 0; i < nLeft; i++)
{
temp[i] = inventory[i].id;
}
i = 0;
iLeft = 0;
iRight = 0;
while (iLeft < nLeft && iRight < nRight)
{
if (temp[iLeft] < inventory[noOfArticles / 2 + iRight].id)
{
inventory[i].id = temp[iLeft];
iLeft = iLeft + 1;
}
else
{
inventory[i].id = inventory[noOfArticles / 2 + iRight].id;
iRight = iRight + 1;
}
i = i + 1;
}
while (iLeft < nLeft)
{
inventory[i].id = temp[iLeft];
i = i + 1;
iLeft = iLeft + 1;
}
}
}
If I'm correct in what you're asking, you want to keep the idCount array relational to the inventory array. I assume, since you're using article as a type that you've either typedef'd a variable to be an article, which would be pointless, or more likely you've built a struct of type article, then made an array of those structs, and called the array inventory.
If this is the case, then the most likely method of keeping them relational is to just include the count in the article struct.
There are methods of making the arrays relational without doing that, but they're pointless, because a simple four-line struct would do the trick, even if that struct was a wrapper around a different struct, or a header for another struct.
When sorting your records, you only assign the id member of your struct:
inventory[foo].id = inventory[bar].id;
You should assign the complete struct:
inventory[foo] = inventory[bar];
Just remember that temporaries must be of type article an not int so they allso can be assigne a complete struct and not only an id value

Resources