cass
cass

Reputation: 31

is it possible to make an array with multiple types of data?

i'm new to coding and currently doing it in c, i have to write a program that reads N elements given by the user and saves them in a array. the program has to generate a new array where:

  1. each repeated number in the first array has to appear only once in the second array
  2. each 0 on the first array doesn't have to appear in the second array

it has to work with ints, chars and floats; and it has to have two versions a random elements one and a user given one.

this is what i have for now, it works with ints and chars but not floats

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


int main()
{
    // asks input for array size
    int maxnum;
    printf("How long will the array be? ");
    scanf("%d", &maxnum);
    fflush(stdin);

    char array[maxnum];
    char answer;

    do
    {
        // asks if user wants to input elements or prefers random
        printf("Would you like to input characters (i) or generate random ones (r)?: ");
        scanf("%c", &answer);
        fflush(stdin);
    }
    while(answer != 'i' && answer != 'r');

    if(answer == 'i')
    {
      // asks input for elements of the array
        printf("Enter %d characters for the array: ", maxnum);
        for(int i = 0; i < maxnum; i++)
        {
            scanf("%30s", &array[i]);
        }
    }
    else if(answer == 'r')
    {
        srand(time(0));
        printf("Characters for the array: ", maxnum);
        for(int i = 0; i < maxnum; i++)
        {
            // generates a random number as the element of the array
            array[i] = (rand() % (126 - 33 + 1)) + 33;
            printf("%c ", array[i]);
        }
    }
    printf("\n");

    // loop that goes on for the length of the array
    for(int i = 0; i < maxnum; i++)
    {
        // if the element is a 0, it is deleted from the array
        if(array[i] == '0')
        {
            for(int k = i; k < maxnum; k++)
            {
                array[k] = array[k + 1];
            }
            // the length of the array is shortened by one
            maxnum--;
        }

        // checks the next element
        for(int j = i + 1; j < maxnum;)
        {
            // if the next element is the same, it is deleted
            if(array[i] == array[j])
            {
                for(int k = j; k < maxnum; k++)
                {
                    array[k] = array[k + 1];
                }
                maxnum--;
            }
            else
            {
                j++;
            }
        }
    }

    // prints final array
    printf("Final array: ");
    for(int i = 0; i < maxnum; i++)
    {
        printf("%c ", array[i]);
    }


    printf("\n\n\n");
    return 0;
}

Upvotes: 1

Views: 1106

Answers (1)

Eric Postpischil
Eric Postpischil

Reputation: 224546

C 2018 6.2.5 20 says:

… An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.

So every element in an array must have the same type.

To record different types within an array, you can use structures and unions.

An example of a structure declaration is:

struct CIF
{
    char  c;
    int   i;
    float f;
};

This creates a type named struct CIF. It holds a char, and int, and a float. You can create an instance of such a structure with struct CIF x;. Then you can access members of the structure using .name to access the member with name name:

struct CIF x;
x.c = 'A';
x.i = 7;
x.f = 11.25;

An example of a union declaration is:

union CIF
{
    char  c;
    int   i;
    float f;
};

This creates a type named union CIF. It holds a char, and int, or a float. The same memory is used for each member of the union, so writing one overwrites the others. Normally, you use only one member a time:

union CIF x;
x.c = 'A';
printf("The char is %c.\n", x.c);
x.i = 7;
printf("The int is %d.\n", x.i);
x.f = 11.25;
printf("The float is %g.\n", x.f);

You can use a combination of a structure and a union to hold one of various types as well as a code indicating which type is currently in the union:

struct CIF;
{
    char type;
    union
    {
        char  c;
        int   i;
        float f;
    } u;
};

Now we can use the type member of the structure to remember which type we have in the union member. The union member is named u. We will use the characters 'c', 'i', and 'f' for codes, but we could make up any code we like:

struct CIF x;
x.type = 'i';
x.u.f  = 11.25;
switch (x.type)
{
    case 'c':
        printf("x contains a character, %c.\n", x.u.c);
        break;
    case 'i':
        printf("x contains an int, %d.\n", x.u.i);
        break;
    case 'f':
        printf("x contains a float, %g.\n", x.u.f);
        break;
    default:
        printf("x contains an invalid type code.\n");
        break;
}

Then we can create an array of these structures:

struct CIF x[10];
x[3].type = 'i';
x[3].u.f  = 11.25;
switch (x[3].type)
{
    case 'c':
        printf("x[3] contains a character, %c.\n", x[3].u.c);
        break;
    case 'i':
        printf("x[3] contains an int, %d.\n", x[3].u.i);
        break;
    case 'f':
        printf("x[3] contains a float, %g.\n", x[3].u.f);
        break;
    default:
        printf("x[3] contains an invalid type code.\n");
        break;
}

Two points for further consideration:

  • Enumerations declared with enum may be used for codes.
  • The member name u may be left out of the union inside the structure. This creates an anonymous union. Its members become “direct” members of the structure, so they may be accessed with x.c, x.i., and x.f instead of x.u.c, x.u.i, and x.u.f.

Upvotes: 4

Related Questions