Reputation: 180
I'm trying to pass an array of strings to a function to print to the screen. The first string prints fine. The proceeding strings, however, are null and thus don't print anything. If I get the pointer directly to the first string instead of the array I can increment it by the size of of the character array and everything prints correctly. If I try to increment the pointer to the array of strings that's where I get the null. Why does this happen and how can I correctly print the array. Also I'm using visual studio if that is affecting it any at all given the C standard it uses.
I don't think the error lies with the call because the pointer passed points to the string array address.
//How I'm passing the array
char headings[4][20] = { "Name", "Record Number", "Quantity", "Cost"};
int widths[4] = {20, 20, 20, 20 };
headers(&headings[0][0], &widths[0], 4);
//Function
void headers(char **heads, int *columnWidths, int noOfColumns) {
int headLength = 0;
printf("|");
for (int i = 0; i < noOfColumns; i++) {
headLength += printf("%*s|", *columnWidths, heads);
columnWidths++;
heads ++;
}
printf("\n");
for (int i = 0; i < headLength+1; i++) {
printf("-");
}
printf("\n");
}
This is the output that I get:
| Name| | | |
but I'm expecting this output:
| Name| Record Number| Quantity| Cost|
Upvotes: 0
Views: 94
Reputation: 5151
You would need to pass headings
into your function, not the address of the first character of the first function. But in C multidimensional arrays are a complete distinct type and the memory layout differs significantly from array of char *
.
This is a working variant, which supports arbitrary dimensions, unlike the accepted solution which only supports the array dimensions 4 string with 20 chars each:
#include <stdio.h>
#include <string.h>
//Function
void headers(const char **heads, int *columnWidths) {
int headLength = 0;
printf("|");
while (*heads) {
headLength += printf("%*s|", *columnWidths, *heads);
columnWidths++;
heads ++;
}
printf("\n");
for (int i = 0; i < headLength+1; i++) {
printf("-");
}
printf("\n");
}
int main(){
const char *headings[] = { "Name", "Record Number", "Quantity", "Cost", 0};
int widths[4] = {20, 20, 20, 20};
headers(headings, &widths[0]);
}
I don't think the error lies with the call because the pointer passed points to the string array address.
No. The pointer to the string array is called headings
. This is an array of char, with two dimensions. It is not possible to iterate over the individual strings without knowledge of the layout of the array.
Instead it is usually better to define an array of char *
and initialize this with the individual strings. You can see how the definition of the array content looks exactly the same as in the multidimensional array variant, but the memory layout is very different, and it is now possible to iterate over the strings like you initially intended.
Upvotes: 1
Reputation: 3461
If you have a 2D Array heading
, your headers
function should also accept a 2D array. Although arrays generally decay to pointers when passed to functions, the type char** heads
is not the same as char headings[4][20]
. And your compiler should warn you about it also.
The following bit of code prints the correct output.
#include <stdio.h>
#include <string.h>
//Function
void headers(char heads[4][20], int *columnWidths, int noOfColumns) {
int headLength = 0;
printf("|");
for (int i = 0; i < noOfColumns; i++) {
headLength += printf("%*s|", *columnWidths, *heads);
columnWidths++;
heads ++;
}
printf("\n");
for (int i = 0; i < headLength+1; i++) {
printf("-");
}
printf("\n");
}
int main(){
char headings[4][20] = { "Name", "Record Number", "Quantity", "Cost"};
int widths[4] = {20, 20, 20, 20};
headers(headings, &widths[0], 4);
}
Note: you could also change the headers
function to accept char heads[][20]
, but not char[][]
as that would give you an obvious compiler error.
Upvotes: 2