Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with passing arrays as parameters

Tags:

arrays

c

I am a novice programmer in C and am running into an issue that is almost painfully simple. I am writing a basic program that creates two arrays, one of student names and one of student ID numbers, then sorts them and prints them in various ways, and finally allows the user to search the arrays by ID number. Here is the code:

#include <stdio.h>
#include <string.h>
#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32

int main()
{   
    // Student info arrays
    char NAME[ARRAY_SIZE][MAX_NAME_LENGTH];
    int ID[ARRAY_SIZE];

    // Array for student IDs, shifted twice to the right
    int shiftedID[ARRAY_SIZE];

    // Boolean value to keep while loop running and
    // the ID search prompt repeating
    int loop = 1;

    // Counter variable for the for loop   
    int counter;
    // Gets input values for the student info arrays
    for (counter = 0; counter < ARRAY_SIZE; counter++)
    {   
        printf("Input student name: ");
        scanf("%s", NAME[counter]);

        printf("Input student ID: ");
        scanf("%d", &ID[counter]);
    }

    // Sorts the arrays
    sort(NAME, ID);

    // Prints the arrays
    print_array(&NAME, ID);

    // Shifts the ID value two bits to the right
    shiftright(ID, shiftedID);

    print_array(NAME, shiftedID);

    // Repeatedely prompts the user for an ID to
    // search for
    while(loop == 1)
    {
        search_id(NAME, ID);
    }
}

And here are the function definitions:

#define ARRAY_SIZE 3
#define MAX_NAME_LENGTH 32
// Sorts the two arrays by student ID. (Bubble sort)
void sort(char **nameArray, int idArray[])
{   

    // Counter variables for the for loop
    int firstCounter = 0;
    int secondCounter = 0;
    for(firstCounter = 0; firstCounter < ARRAY_SIZE; firstCounter++)
    {
        for(secondCounter = 0; secondCounter < ARRAY_SIZE - 1;   
                secondCounter++)
        {
            if(idArray[secondCounter] > idArray[secondCounter + 1])
            {

                // Temporary variables for the sort algorithm
                int tempInt = 0;
                char tempName[32];

                tempInt = idArray[secondCounter + 1];
                idArray[secondCounter + 1] = idArray[secondCounter];
                idArray[secondCounter] = tempInt;

                strcpy(tempName, nameArray[secondCounter + 1]);
                strcpy(nameArray[secondCounter + 1],   
                      nameArray[secondCounter]);
                strcpy(nameArray[secondCounter], tempName);
            }
        }
    }
}
// Searches the ID array for a user input student
// ID and prints the corresponding student's info.
void search_id(char **nameArray, int idArray[])
{
    // A boolean value representing whether or not
    // the input ID value was found
    int isFound = 0;

    // The input ID the user is searching for
    int searchID = 0;

    printf("Input student ID to search for: ");
    scanf("%d", &searchID);

    // Counter variable for the for loop
    int counter = 0;
    while (counter < ARRAY_SIZE && isFound == 0)
    {
        counter++;
        if (idArray[counter] == searchID)
        {
            // Prints the name associated with the input ID
            isFound = 1; 
            printf("%s", nameArray[counter]);
        }
    }

    // If the input ID is not found, prints a failure message.
    if (isFound == 0)
    {
        printf("ID not found.\n");
    }
}

// Prints the name and ID of each student.
void print_array(char **nameArray, int idArray[])
{   
    // Counter variable for the for loop
    int counter = 0;

    printf("Student Name & Student ID: \n");
    for (counter = 0; counter < ARRAY_SIZE; counter++)
    {   
        printf("%s --- %d\n", nameArray[counter], idArray[counter]);
    }
} 

// Shifts the ID value to the right by two bits
void shiftright(int idArray[], int shiftedID[])
{
    // Counter variable for the for loop
    int counter = 0;
    for (counter = 0; counter < ARRAY_SIZE; counter++)
    {
        shiftedID[counter] = idArray[counter] >> 2;
    }
}

I am aware that this program is fairly basic in nature, and more than anything it is an exercise to get me more well versed in a language such as C. I've been working on it for some time, and have worked through several problems, but seem to be stuck on three issues:

  1. If the input ID numbers are not input already in order, a segmentation fault results. If the ID numbers are input already in order, the sort function never passes through the if statement, and no problems arise.

  2. When passing the arrays of names/IDs to the print_array function, the IDs are printed just fine, but the names will be printed either entirely blank or as a series of strange characters.

  3. When searching by ID at the end of the program, the ID number that was entered first (so, the number in ID[0]) displays an ID not found message, where all numbers at index 1 or greater will work fine - aside from the corresponding names that should be printed being printed as blank, as mentioned in the second issue.

Any advice that I can get would be greatly appreciated! I find the power behind the fine details needed in C to be both really interesting but also very confusing, intimidatingly so, and that means any help I can get makes a big difference.

like image 645
Geoiv04 Avatar asked Apr 22 '16 03:04

Geoiv04


People also ask

Can arrays be passed as parameters?

To pass an array as a parameter to a function, pass it as a pointer (since it is a pointer). For example, the following procedure sets the first n cells of array A to 0. Now to use that procedure: int B[100]; zero(B, 100);

Why is not possible to pass an array to a function?

Because the starting address of the array is passed, the called function knows precisely where the array is stored. Therefore, when the called function modifies array elements in its function body, it's modifying the actual elements of the array in their original memory locations. "

Can a function accept an array as a parameter?

In C++, we can pass arrays as an argument to a function. And, also we can return arrays from a function.

How do you pass an array as an argument to a function?

To pass an entire array to a function, only the name of the array is passed as an argument. result = calculateSum(num); However, notice the use of [] in the function definition. This informs the compiler that you are passing a one-dimensional array to the function.


2 Answers

The problem is that you are assuming that char [ARRAY_SIZE][MAX_NAME_LENGTH] and char ** are interchangeable

void sort(char **nameArray, int idArray[])

should be

void sort(char nameArray[][MAX_NAME_LENGTH], int idArray[])

or

void sort(char (*nameArray)[MAX_NAME_LENGTH], int idArray[])

in order to use a pointer to an array of MAX_NAME_LENGTH chars, same for your search_id function.

Take a look to question 6.13 of C-FAQ

like image 117
David Ranieri Avatar answered Sep 26 '22 00:09

David Ranieri


I would advise you to restructure your program. Rather than storing two independent arrays for names and IDs, you can store one array of structs which contain all the necessary data:

typedef struct student
{
    int id;
    char name[MAX_NAME_LENGTH];
} student_t;

student_t students[ARRAY_SIZE];

Now you have a single array which can never become "mismatched" by sorting the IDs without the names, etc.

You can sort an array in C using the standard library function qsort():

qsort(students, ARRAY_SIZE, sizeof(student_t), comparator);

This requires you define a comparator, which is fairly simple. One example would be:

int comparator(const void *lhs, const void *rhs)
{
    const student_t *s1 = lhs, *s2 = rhs;
    return s1->id - s2->id;
}

You can use the same comparator with another standard library function bsearch() to search the array of students after it is sorted:

student_t key = { 42 }; // name doesn't matter, search by ID
student_t* result = bsearch(&key, students, ARRAY_SIZE, sizeof(student_t), comparator);

These standard functions are more efficient than what you had, and require you to write much less code, with fewer chances for mistakes.

like image 27
John Zwinck Avatar answered Sep 25 '22 00:09

John Zwinck