Ciprian Ambrus
Ciprian Ambrus

Reputation: 19

C/C++ multiple scanf in one function

How do I make a function that reads some values from console and then I return them? I mean not a single scanf, multiple scanf in another function and then return the values.

For example:

int main(){
    write();
}

int write(void){
    int a,b;
    printf("Enter an int");
    scanf("%d",&a);
    printf("Enter another int");
    scanf("%d",&b)
    return a,b;
}

I know that C is not C++; I just want an example of C++. Here is the full program that I made. I ask this question because I want to optimize my code. The above function I implemented in my program, but I didn't figure out to make it work, only with pointers.

#include <stdio.h>
#include <stdlib.h>
#define MAX 32

void read(int*x,int*y);

void write(int m[][MAX],int x,int y);

void display(int sir[][MAX],int x,int y);

int main(){
    int x,y,m,n,a,b,i,k;
    int matrice1[MAX][MAX]={0},matrice2[MAX][MAX]={0},result[MAX][MAX]={0},result2[MAX][MAX]={0};
    read(&x,&y); //this is what i want to not use direct addreses if is possible
    write(matrice1,x,y);
    m=x;
    n=y;
    read(&x,&y);
    write(matrice2,x,y);
    system("cls");
    printf("Prima matrice: \n");
    for(i=0;i<m;i++){
        for(k=0;k<n;k++){
            printf(" %d",matrice1[i][k]);
        }
        printf("\n");
    }
    display(matrice1,m,n);
    printf("\nA doua matrice: \n");
    for(i=0;i<x;i++){
        for(k=0;k<y;k++){
            printf(" %d",matrice2[i][k]);
        }
        printf("\n");
    }
    display(matrice2,x,y);
    printf("\nSuma matricelor: \n");
    if(x>m){
        a=x;
    }
    else
        a=m;
    if(y>n){
        b=y;
    }
    else
        b=n;
    for(i=0;i<a;i++){
        for(k=0;k<b;k++){
            result[i][k]=matrice1[i][k]+matrice2[i][k];
            printf(" %d",result[i][k]);
            if(matrice1[i][k]%2!=0 && matrice2[i][k]%2!=0){
                result2[i][k]=matrice1[i][k]+matrice2[i][k];
            }
        }
        printf("\n");
    }
    printf("\nSuma matricelor impare<doar daca ambele sunt impare>: \n");
    for(i=0;i<a;i++){
        for(k=0;k<b;k++){
            printf(" %d",result2[i][k]);
        }
        printf("\n");
    }
    return 0;
}

void write(int m[][MAX],int x,int y){
    int i,k;
    for(i=0;i<x;i++){
        for(k=0;k<y;k++){
            printf("elementul de pe linia %d, coloana %d: ",i,k);
            scanf("%d",&m[i][k]);
        }
    }
}

void read(int*x,int*y){
    printf("\nIntroduceti numarul de randuri a matricei: ");
    scanf("%d",x);
    printf("Introduceti numarul de coloane a matricei: ");
    scanf("%d",y);
    printf("\nIntroduceti elementele matricei.\n");
}

void display(int sir[][MAX],int x,int y){
    int i,k;
    for(i=0;i<x;i++){
        for(k=0;k<y;k++){
            if(sir[i][k]%2==0)
                printf("numar par, pozitia %d,%d: %d\n",i,k,sir[i][k]);
        }
    }
}

Upvotes: 0

Views: 521

Answers (2)

John Bode
John Bode

Reputation: 123488

Neither C nor C++ functions can return multiple values; not that it matters, since neither C nor C++ support multiple assignment either.

With C, you have the following choices:

  1. If all the objects are the same type and logically related (i.e., a list of grades, temperatures, etc.), pass an array as the function argument, write to elements of the array:
    void foo( int *arr, size_t arrSize )
    {
      ...
      scanf( "%d", &arr[i] );
      ...
    }
    which would be called as:
    int values[N];
    ...
    foo( values, N );
    
    Alternately, you can have the function dynamically allocate a block of memory to hold its inputs, and return the pointer to that allocated block:
    /**
     * Stores inputs to a dynamically-allocated block of memory.
     *
     * Outputs:
     *
     *  arrSize  - Number of array elements allocated
     *  arrCount - Number of array elements assigned
     */
    int *foo( size_t *arrSize, size_t *arrCount )
    {
      *arrSize = INITIAL_SIZE; // some size that covers most of your use cases
      *arrCount = 0;
      /**
       * Allocate the array
       */
      int *arr = malloc( sizeof *arr * *arrSize );
      if ( !arr )
         // allocation failed, handle as appropriate
      int val;
      while ( scanf( "%d", &val ) == 1 )
      {
        /**
         * If we've filled the array, extend it by doubling its size
         */
        if ( *arrCount == *arrSize )
        {
          int *tmp = realloc( arr, sizeof *arr * (*arrSize * 2) );
          if ( tmp )
          {
            arr = tmp;
            *arrSize *= 2;
          }
          else
          {
            // failed to extend the array, handle as appropriate
          }
        }
        arr[(*arrCount)++] = val;
      }
      return arr;
    }
    
    which would be called as:
    size_t size = 0, count = 0;
    int *values = foo( &size, &count );
    ...
    free( values ); // need to release the memory when you're done with it
    
    Note that C functions cannot return objects of array type; that is, you can't do:
    int foo(void)[N] // illegal syntax
    {
      int arr[N];
      ...
      return arr; 
    }
    
    Nor can you return a pointer corresponding to a local array, since the array ceases to exist once the function exits:
    int *foo( void )
    {
      int arr[N];
      ...
      return arr; // pointer will be invalid after function exits
    }
    
  2. If the objects have different types, or are not logically part of the same group, then use multiple pointers in the argument list:
    void foo( int *p1, double *p2 )
    {
      ...
      scanf( "%d", p1 );
      ...
      scanf( "%lf", p2 );
      ...
    }
    
    and call it as
    int bar;
    double bletch;
    ...
    foo( &bar, &bletch );
    

C++ gives you some different options:

  1. If all the items have the same type and are logically related, use a vector to store them and return the vector:
    std::vector<int> foo( void )
    {
      std::vector<int> arr;
      size_t i = 0;
      ...
      std::cin >> arr[i++];
      ...
      return arr;
    }
    
    and call it as:
    std::vector<int> values = foo();
    
  2. If the items have different types or are not logically related, then use multiple references to those items:
    void foo( int& bar, double& bletch )
    {
      ...
      std::cin >> bar;
      ...
      std::cin >> bletch;
    }
    
    and call it as
    int x;
    double y;
    ...
    foo( x, y ); // no & operator since we're using references in the called function
    

Upvotes: 2

user4520
user4520

Reputation: 3457

Please note that C and C++ are different languages so the code will also be different.

For C, I'd suggest the following approach:

int readInts(int intArr[], size_t maxInts)
{
    int i = 0;
    while (i < maxInts && scanf("%d", &intArr[i]) == 1) { i++; }
    return i;
}

Call it like this:

int myInts[100];
numInts = readInts(myInts, sizeof(myInts) / sizeof(myInts[0]);


In C++ one should avoid manual memory management whenever possible, therefore I'd do this:

std::vector<int> readInts()
{
    int x;
    std::vector<int> result;
    while (std::cin >> x)
    {
        result.push_back(x);
    }

    return result;
}

Upvotes: 3

Related Questions