Форматированный массив ввода int - PullRequest
0 голосов
/ 19 мая 2018

Мне нужно иметь возможность ввести массив int s и удерживать его в наборе внутри struct, однако по какой-то причине он не будет читать числа в массив:

#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;
}

вывод, который я получаю:

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

и нет необходимости говорить, что print_set ничего не печатает.

1 Ответ

0 голосов
/ 19 мая 2018

В

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

вы увеличиваете i при записи значения.Когда вы пытаетесь напечатать s.arr[i], вы на один шаг впереди того места, где вы сохранили значение.

Увеличение после печати?

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

Вы работаете int read_set(set s,...)берет копию set s и помещает в нее вещи.К тому времени, когда вы вернетесь к вызывающей функции в main, скопированный вами set не изменится.Вам нужно отправить указатели на переменные, чтобы изменить их:

int read_set(set *ps,...)

, а затем вызывающему коду потребуется отправить адрес x = read_set(&SETA, 2, 3, 4, -1);, чтобы вы могли изменить то, что находится в наборе.Альтернатива - вернуть заполненную структуру.

Еще две вещи, о которых стоит подумать.Во-первых, вы можете объявить свой набор внутри main - у него нет причин быть глобальным.И вам не нужно это делать.

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

Также обратите внимание на функцию печати.Он использует while (*iptr++), поэтому проверяет 0 или NULL, чтобы остановить цикл.Я не вижу никаких нулей, так что это нужно переосмыслить.И хотите ли вы иметь set, который не будет отображать ничего, кроме 0?

...