Formatted input array int

72 Views Asked by At

I need to be able to enter array of ints and hold it in a set inside a struct, however for some reason it won't read the numbers into the array:

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

#define MAX 100

typedef struct set {
    int arr[MAX];
} set;

set SETA;

int read_set(set,...);
void print_set(set);

int main(){
    int x;
    x=read_set(SETA,2,3,4,-1);
    printf("%d numbers were read\n",x);

    print_set(SETA);
    return 0;
 }

void print_set(set s){
    int *iptr;
    iptr=s.arr;

    while(*iptr++){
        printf("%d ",*iptr);
    }
}


int read_set(set s,...){
    va_list ap;
    int i=0;
    int c=0;

    va_start(ap,s);

    while( *ap != -1){
        s.arr[i++]=va_arg(ap,int);
        printf("%d was entered\n",s.arr[i]);
        c++;
    }
    va_end(ap);
    return c;
}

the output I get is:

0 was entered  
0 was entered  
0 was entered  
3 numbers were read  

and needless to say that print_set prints nothing.

1

There are 1 best solutions below

10
On BEST ANSWER

In

while( *ap != -1){
    s.arr[i++]=va_arg(ap,int);
    printf("%d was entered\n",s.arr[i]);
    c++;
}

you increment i when you record the value. When you try to print s.arr[i] you are one ahead of where you stored the value.

Increment after the print?

while( *ap != -1){
    s.arr[i]=va_arg(ap,int);
    printf("%d was entered\n",s.arr[i]);
    i++;
    c++;
}

You function int read_set(set s,...) takes a copy of a set s and puts stuff in it. By the time you get back to the calling function in main, the set that you copied in is unchanged. You need to send pointers to variables to change them:

int read_set(set *ps,...)

and the calling code would then need to send the address x = read_set(&SETA, 2, 3, 4, -1); so you can change what's in the set. An alternative is to return the filled structure.

Two other things to think about. First, you could declare your set inside main - it has no reason to be global. And you don't need to captilaise it.

int main() {
    set setA; //style/design point. Also don't shout.
    //... etc
}

Also, look at your print function. It uses while (*iptr++), so is checking of 0s or some kind of NULL to stop looping. I can't see any zeros so this needs a re-think. And, do you want to have a set that won't display anything beyond a 0?