PDA

View Full Version : Variable Length Array in C




CsRookie
Apr 19, 2011, 08:15 PM
#define SIZE 10
#define STUDENT_NUM 10
#define EXAM_GRADE 3

int main()

{
int ids [SIZE],i, id;
double scores [SIZE];
int total = 0.0;
int GPA;

for (i=0; i < SIZE; i++)
{

printf("Enter student ID number (negative to stop)\n");
scanf("%d", &ids[i]);
printf ("Enter exam score 1 for student %d now\n", ids[i]);
scanf("%d", &scores[i]);
printf ("Enter exam score 2 for student %d now\n",ids[i]);
scanf("%d", &scores[i]);
printf ("Enter exam score 3 for student %d now\n",ids[i]);
scanf("%d", &scores[i]);

}



What type of statement, or loop do I need to add in order to be able to cut this off when I want to (with a negative student id). I tried adding a nested while loop but it is not working but part of the issue is im not sure if im looking for the right thing. I tried while ids > 0. Can someone point me in the right direction? Thanks in advance :apple:



KnightWRX
Apr 19, 2011, 08:20 PM
Just change your loop's exit condition to check that the id entered is positive ? You'll have to rework some of your output and input code there to check the id at the proper time. What other looping statements have you learned that you think would be a better fit ?

The other problem you'll be facing is that your array has a static size of 10. After 10 ids, if you still don't encounter a negative id, you'll have a buffer overflow.

Oh and you're overwriting your scores. You only ever keep exam score 3.

CsRookie
Apr 19, 2011, 08:32 PM
Just change your loop's exit condition to check that the id entered is positive ? You'll have to rework some of your output and input code there to check the id at the proper time. What other looping statements have you learned that you think would be a better fit ?

The other problem you'll be facing is that your array has a static size of 10. After 10 ids, if you still don't encounter a negative id, you'll have a buffer overflow.

Oh and you're overwriting your scores. You only ever keep exam score 3.

You are right, how do I avoid overflow? Do I need to declare it differently? Is there a way to declare a variable length array that still fills up at 10 or displays a message after 10 not allowing anymore?
I have a good understanding of the majority of the loops (while,dowhile, for, etc.) I am more confused on arrays. I would think the easiest way would be to say


do
{

}while(ids > 0);

but I do not think ids is the condition I should be testing.

chown33
Apr 19, 2011, 09:02 PM
Look up the break keyword for a looping context. break also has a use in switch context, which isn't relevant here.

Typical use of break in a looping context:
if ( some terminating condition )
break;



The other problem you'll be facing is that your array has a static size of 10. After 10 ids, if you still don't encounter a negative id, you'll have a buffer overflow.

I don't see it: the loop is bounded by i < SIZE, where SIZE is the length of both arrays.

That doesn't mean there aren't significant bugs in the posted code. Just that I don't see where either array will overflow, as given.

A whole lot more thought needs to go into the design. Such as the fact that up to 30 scores might be stored (3 per student, max 10 students), but the array for storing scores is plainly insufficient for this task.

Bill McEnaney
Apr 19, 2011, 09:13 PM
[QUOTE=CsRookie;12424376]

#define SIZE 10
#define STUDENT_NUM 10
#define EXAM_GRADE 3

int main()

{
int ids [SIZE],i, id;
double scores [SIZE];
int total = 0.0;
int GPA;

for (i=0; i < SIZE; i++)
{

printf("Enter student ID number (negative to stop)\n");
scanf("%d", &ids[i]);
printf ("Enter exam score 1 for student %d now\n", ids[i]);
scanf("%d", &scores[i]);
printf ("Enter exam score 2 for student %d now\n",ids[i]);
scanf("%d", &scores[i]);
printf ("Enter exam score 3 for student %d now\n",ids[i]);
scanf("%d", &scores[i]);

}



Correct me if I'm wrong. But I think the blue scanf overwrites what the red one put into scores[i] and that the green scanf what the blue one put there.

CsRookie
Apr 19, 2011, 09:30 PM
Look up the break keyword for a looping context. break also has a use in switch context, which isn't relevant here.

Typical use of break in a looping context:
if ( some terminating condition )
break;





I don't see it: the loop is bounded by i < SIZE, where SIZE is the length of both arrays.

That doesn't mean there aren't significant bugs in the posted code. Just that I don't see where either array will overflow, as given.

A whole lot more thought needs to go into the design. Such as the fact that up to 30 scores might be stored (3 per student, max 10 students), but the array for storing scores is plainly insufficient for this task.


Thank you very much!

I added more arrays now such as score1,score2,score3 to help with the fact that 30 scores needed to be displayed and the break statement works great for exiting. Thank you again.

Another question I have is, how do I make it so only the arrays which have information pertaining to the program display at the end?

For example if I stop the program after 3 students and scores the display at the end with gpa and averages etc still shows all 10 arrays slots and has huge strings of numbers displaying. How do I show only those with data?

chown33
Apr 19, 2011, 09:37 PM
How do I show only those with data?
Keep the array index when you break the loop.

CsRookie
Apr 19, 2011, 09:53 PM
Keep the array index when you break the loop.

got it working now.

Thank you again for the help. :apple:

CsRookie
Apr 20, 2011, 12:06 AM
#include <stdio.h>

#define SIZE 10
#define STUDENT_ID 10
#define EXAM_SCORE 3

int main()

{
int ids [SIZE],i;
double scores1 [SIZE];
double scores2 [SIZE];
double scores3[SIZE];
int total = 0.0;
double sum1=0;
double sum2=0;
double sum3=0;
double studentAvg;
double a =0, b = 0, c=0,d=0,f=0;
int count=0.00;

for (i=0; i < SIZE; i++)

{

printf("Enter student ID number (negative to stop)\n");
scanf("%d", &ids[i]);
if (ids[i] < 0)
break;
printf ("Enter exam score 1 for student %d now\n", ids[i]);
scanf("%lf", &scores1[i]);
sum1+=scores1[i];
printf("Enter exam score 2 for student %d now\n",ids[i]);
scanf("%lf", &scores2[i]);
sum2+=scores2[i];
printf("Enter exam score 3 for student %d now\n",ids[i]);
scanf("%lf", &scores3[i]);
sum3+=scores3[i];
++count;

}
printf("\n----------------\n");
printf("Summary\n");
printf("-----------------\n");

printf("\n-------------------------------------------------------------------\n");
printf("ID # Exam 1 Exam 2 Exam 3 Average Grade ");
printf("\n-------------------------------------------------------------------\n");




for (i = 0; i < SIZE; i++)
{
if (ids[i] < 0)
break;
printf("\nID %d \t", ids[i]);
printf("%.2f ", scores1[i]);
printf("%.2f ", scores2[i]);
printf("%.2f ", scores3[i]);
printf("%.2f ",(scores1[i]+scores2[i]+scores3[i])/3);
if ((scores1[i]+scores2[i]+scores3[i])/3 > 89.5)
printf("A\n");
else if ((scores1[i]+scores2[i]+scores3[i])/3 > 79.5)
printf("B\n");
else if ((scores1[i]+scores2[i]+scores3[i])/3 > 69.5)
printf("C\n");
else if ((scores1[i]+scores2[i]+scores3[i])/3 > 59.5)
printf("D\n");
else if ((scores1[i]+scores2[i]+scores3[i])/3 < 59.4)
printf("F\n");


if ((scores1[i]+scores2[i]+scores3[i])/3 > 89.5)
++a;
else if ((scores1[i]+scores2[i]+scores3[i])/3 > 79.5)
++b;
else if ((scores1[i]+scores2[i]+scores3[i])/3 > 69.5)
++c;
else if ((scores1[i]+scores2[i]+scores3[i])/3 > 59.5)
++d;
else if ((scores1[i]+scores2[i]+scores3[i])/3 < 59.4)
++f;
}

printf("\n\nSummary Report\n");
printf("\n-----------------\n");
printf("\n");


printf("Exam 1 average %.2f", sum1/count);
printf("\n");
printf("Exam 2 average %.2f", sum2/count);
printf("\n");
printf("Exam 3 average %.2f", sum3/count);
printf("\n");
printf("Overall average %.2f", (sum1+sum2+sum3)/count);
printf("\n");

printf("Class GPA = %.2f", (a*4+b*3+c*2+d*1+f*0)/count);

printf("\n");






return 0;
}





Can anyone see why my overall average is off? it seems to only add the three sums together and completely ignores dividing by the count.

Also I am having issues trying to sort the data, I would like to sort by highest average, what direction do I need to look into for that. I am trying to work with bubble sorting but I am struggling to apply the concept in relation to this program.

ender land
Apr 20, 2011, 01:18 AM
you can get weird results for a variety of reasons when doing something that amounts to

double / integer

printf sometimes does REALLY weird display things when you put integers as floats, if you are using xcode try using the debugger and putting a breakpoint there or create a temporary variable to see.

Otherwise, you might want to try
(sum1+sum2+sum3)/(double)count);

to ensure you are actually getting a %f value to output.

you can also do
printf("Exam 1 average %.2f \n", sum1/count);

and save yourself a line of code btw :)

Why are you using references to those arrays? Why not just use the absolute reference? That seems a bit more complicated than would be needed. You might also be able to clean up that if/elseif stuff if you look up Switch statements, they more or less are made to do what you are doing :)

Bill McEnaney
Apr 20, 2011, 04:02 AM
Why not something like this?

average = (scores1[i] + scores2[i] + scores3[i]) / 3.0;
if (average > 89.5)
a++;
else if (average > 79.5)
b++;
else if (average > 69.5)
c++;
else if (average > 59.5)
d++;
else
f++;

I don't see any way to use a switch statement in our friend's program because I doubt that C would let us write anything like this.
switch (average)
{
case > 89.5:
a++;
break;

case > 79.5:
b++;
break;

case > 69.5:
c++;
break;

case > 59.5:
d++;
break;

default:
f++;
}

dmi
Apr 20, 2011, 07:08 AM
switch (average)
{
case > 89.5:
a++;
break;

case > 79.5:
b++;
break;

case > 69.5:
c++;
break;

case > 59.5:
d++;
break;

default:
f++;
}

switch ((int)((average+.5)/10))
{

case 8:
b++;
break;

case 7:
c++;
break;

case 6:
d++;
break;

case 0: case 1: case 2: case 3: case 4: case 5:
f++;
break;

default:
a++;
}

Bill McEnaney
Apr 20, 2011, 08:32 AM
Dmi, that was clever.