1

I am stuck on a programming assignment in C. The user has to enter a number specifying the size of an array no bigger than 10 elements which will store the names of students. This must be done in a separate function from the main function called getNames. Each name can be up to 14 characters and getNames must be invoked from within the main function. Here is my code:

#include <stdio.h> 

void getNames(char *a, int n){
    int i;
    for(i=0; i<n; i++){
        printf("Enter a name: ");
        scanf("%s", &a[i]);
    } 

}

void printNames(char *a, int n){
    int i;

    for(i=0; i<n; i++){
        printf("%s\n", &a[i]);
    }
}

void main(){
    int num; //number of names in array 'names'
    printf("Num of students: ");
    scanf("%d", &num);

    char names[num][15]; //each name is 14 characters plus
                         //a null character
    getNames(names[num], num);
    printNames(names[num], num);

}

The code compiles and runs without syntax errors but the array is not filled correctly. For example:

Num of students: 5
Enter a name: Jeb
Enter a name: Bob
Enter a name: Bill
Enter a name: Val
Enter a name: Matt

returns:

JBBVMatt
BBVMatt
BVMatt
VMatt
Matt

Clearly there is an issue writing to the array but I am not sure what it is.

For this assignment our professor was adamant that we cannot use any global variables. His wording was rather vague about how we should implement this. My first thought would be to move the for loop in getNames into the main function and just calling getNames repeatedly but I would like a solution that incorporates that into getNames. I'm new to C, having mostly dealt with Java so please bear with me. Any help would be appreciated.

0

2 Answers 2

1

If the code you have posted is exactly the code you are using, then it is invoking undefined behavior by accessing a memory location that your program does not own: getNames(names[num], num);.
Array indexing in C goes from 0 to n-1. (or from names[0]-names[num-1]) Same in other similar calls.

next issue is the function prototypes to accommodate;

char names[num][15];  

The function needs to send the address of an array of arrays. See edits on code to show the difference.

Next issue are the following statements, see comments after each

getNames(names[num], num);//names[n] points to memory beyond what is owned.
                          //should point to address of beginning of memory &names[0]
printNames(names[num], num);//ditto

Working code example, see edits to explain:

//void getNames(char *a, int n){//change *a to either a[][15] or (*a)
void getNames(char a[][15], int n){
    int i;
    for(i=0; i<n; i++){
        printf("Enter a name: ");
        scanf("%s", a[i]);
    } 

}

 //void printNames(char *a, int n){ //change *a to either a[][15] or (*a)
 void printNames(char a[][15], int n){
    int i;

    for(i=0; i<n; i++){
        printf("%s\n", a[i]);
    }
}

void main(){
    int num; //number of names in array 'names'
    printf("Num of students: ");
    scanf("%d", &num);

    char names[num][15]; //each name is 14 characters plus
                         //a null character
    //getNames(names[num], num);//names[n] points to memory beyond what is owned.
    //printNames(names[num], num);//ditto
    getNames(&names[0], num);
    printNames(&names[0], num);

}
Sign up to request clarification or add additional context in comments.

7 Comments

Thank you kind stranger! This worked out fine for me. I really appreciate the input. We haven't even covered memory allocation yet so this assignment feels like I'm in a cave without a flashlight trying to feel my way through.
I would swap a and n in the parameters, then you could write (assuming a modern compiler) void getNames(int n, char a[n][15]) { .... }, which may be easier to grasp for a beginner.
@HAL9000 - Because there is no guarantee that function arguments are recognized in any particular order, It is undefined. eg if char a[n][15] were seen in a call to getNames before int n, then n would be undefined. But otherwise, it would be a good idea. Thanks
Yes, the order of evaluating parameters before calling a function is not defined, but as soon as the function is called, all the parameter values are defined. And modern c (AFAIK) does allow an integer argument in a function parameter be used as array size in another, but the size parameter must come before the array parameter.
Some additional explanation: There is nothing in getNames(int n, char a[n][15]) that demands that n has been calculated before a, as long as a isn't referenced before n exist. And that doesn't happen before inside the function where both n and a are guaranteed to exist.
|
0

you can do following

  1. Method

in main function call as below

getNames(names, num);
printNames(names, num);

and change the functions as below

void getNames(char (*a)[15], int n) 
{
   ...
}

void printNames(char (*a)[15], int n)
{
   ...
}
  1. Method , in main calls remain same

void getNames(char a[5][15], int n)

and

void printNames(char a[5][15], int n)

But instead of using hard values better to use #define row and col sizes

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.