Passing A Buffer
You could define an array in the caller and pass that into employee_Input1
; then there is no need to return anything.
Note that you should use a maximum field width specifier with %s
to avoid buffer overflow, and this specification should be one less than the buffer size to include space for the \0
character that terminates a string. It is also a good idea to use a generous buffer size instead of minimal sizes like 20.
scanf
returns the number of assignments made, or EOF
on error. You should get in the habit of checking this (and all return values) to be sure that input is as expected.
#include <stdio.h>
#include <stdlib.h> // for `exit`
void employee_input_1(char *buffer) {
printf("Enter an employee name: ");
if ((scanf("%1023s", buffer) != 1)) { // specify maximum field width
printf("Input error\n");
exit(EXIT_FAILURE);
}
}
int main(void) {
char buffer[1024];
employee_input_1(buffer);
// Now you can do stuff with `buffer`:
printf("Employee: %s\n", buffer);
}
Returning A Struct
You can't return arrays in C, and you can't return pointers to local objects in C, but you can return structs. This gives rise to another solution: you can wrap an array in a struct and return the struct from a function:
#include <stdio.h>
#include <stdlib.h> // for `exit`
struct employee_name {
char first[1024];
char last[1024];
};
struct employee_name employee_input_2(void) {
struct employee_name name = { 0 };
printf("Enter employee's first name: ");
if ((scanf("%1023s", name.first)) != 1) {
printf("Input error\n");
exit(EXIT_FAILURE);
}
printf("Enter employee's last name: ");
if ((scanf("%1023s", name.last)) != 1) {
printf("Input error\n");
exit(EXIT_FAILURE);
}
return name;
}
int main(void) {
struct employee_name some_name = employee_input_2();
// Now you can do stuff with `some_name`:
printf("Employee: %s, %s\n", some_name.last, some_name.first);
}
Passing A Dynamically Allocated Buffer
You can use malloc
to dynamically allocate memory for a buffer and then pass that buffer to employee_input_1
just as before:
#include <stdio.h>
#include <stdlib.h>
void employee_input_1(char *buffer) {
printf("Enter an employee name: ");
if ((scanf("%1023s", buffer) != 1)) { // specify maximum field width to include `\0`
printf("Input error\n");
exit(EXIT_FAILURE);
}
}
int main(void) {
// Using `malloc`:
char *buffer = malloc(1024);
if (buffer == NULL) {
printf("Allocation failure\n");
exit(EXIT_FAILURE);
}
// Use `employee_input_1` as before:
employee_input_1(buffer);
printf("Employee: %s\n", buffer);
// Free memory allocation when finished:
free(buffer);
}
You should check the value returned from malloc
: a pointer to the allocation is returned, or a null pointer on error. If there is an error you should handle that error; here the program just prints an error message and exits.
You need to free memory allocated with malloc
when you are finished with it to avoid memory leaks.
Allocating Memory In The Called Function
You can also use malloc
to allocate memory from within the called function and return a pointer to this dynamic allocation. You still need to free the allocation when you are finished with it, but this time the caller will be responsible for freeing the allocated memory. You also still need to check for allocation failures; this can be done within the called function as it is here, or the function can return the pointer returned by malloc
and the caller can check for errors by checking for a null pointer.
#include <stdio.h>
#include <stdlib.h>
char * employee_input_3(void) {
char *buffer = malloc(1024);
if (buffer == NULL) {
printf("Allocation failure\n");
exit(EXIT_FAILURE);
}
printf("Enter an employee name: ");
if ((scanf("%1023s", buffer) != 1)) { // specify maximum field width to include `\0`
printf("Input error\n");
exit(EXIT_FAILURE);
}
return buffer;
}
int main(void) {
// Dynamic allocation within the called function:
char *buffer = employee_input_3();
printf("Employee: %s\n", buffer);
// Free memory allocation when finished:
free(buffer);
}