Two dimensional array with char pointer in c
up vote
0
down vote
favorite
In the following code I am trying for each band to get the number of band members. I've tried a number of things but nothing works. The following looks like it should but doesn't.
If any one could point out what I'm doing wrong it would be greatly appreciated.
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int i;
int j;
int numBands;
int numMembers;
int limit = 4;
struct band {
char name[10];
char *members[20];
};
const struct band bands =
{ {"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
for ( j = 0; j < numMembers; ++j )
printf ("t%s", bands[i].members[j]);
printf ("n");
}
return 0;
}
c arrays pointers struct char
add a comment |
up vote
0
down vote
favorite
In the following code I am trying for each band to get the number of band members. I've tried a number of things but nothing works. The following looks like it should but doesn't.
If any one could point out what I'm doing wrong it would be greatly appreciated.
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int i;
int j;
int numBands;
int numMembers;
int limit = 4;
struct band {
char name[10];
char *members[20];
};
const struct band bands =
{ {"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
for ( j = 0; j < numMembers; ++j )
printf ("t%s", bands[i].members[j]);
printf ("n");
}
return 0;
}
c arrays pointers struct char
Design question: why use a fixed array sizechar name[10]
for band names, yet a character pointer for band members? I'd expect something likechar *name; char *members[20];
orchar name[10]; char members[20][30];
– chux
Nov 7 at 23:16
The first line is a syntax error
– M.M
Nov 7 at 23:20
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
In the following code I am trying for each band to get the number of band members. I've tried a number of things but nothing works. The following looks like it should but doesn't.
If any one could point out what I'm doing wrong it would be greatly appreciated.
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int i;
int j;
int numBands;
int numMembers;
int limit = 4;
struct band {
char name[10];
char *members[20];
};
const struct band bands =
{ {"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
for ( j = 0; j < numMembers; ++j )
printf ("t%s", bands[i].members[j]);
printf ("n");
}
return 0;
}
c arrays pointers struct char
In the following code I am trying for each band to get the number of band members. I've tried a number of things but nothing works. The following looks like it should but doesn't.
If any one could point out what I'm doing wrong it would be greatly appreciated.
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
int i;
int j;
int numBands;
int numMembers;
int limit = 4;
struct band {
char name[10];
char *members[20];
};
const struct band bands =
{ {"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
for ( j = 0; j < numMembers; ++j )
printf ("t%s", bands[i].members[j]);
printf ("n");
}
return 0;
}
c arrays pointers struct char
c arrays pointers struct char
asked Nov 7 at 21:54
Griffau
103
103
Design question: why use a fixed array sizechar name[10]
for band names, yet a character pointer for band members? I'd expect something likechar *name; char *members[20];
orchar name[10]; char members[20][30];
– chux
Nov 7 at 23:16
The first line is a syntax error
– M.M
Nov 7 at 23:20
add a comment |
Design question: why use a fixed array sizechar name[10]
for band names, yet a character pointer for band members? I'd expect something likechar *name; char *members[20];
orchar name[10]; char members[20][30];
– chux
Nov 7 at 23:16
The first line is a syntax error
– M.M
Nov 7 at 23:20
Design question: why use a fixed array size
char name[10]
for band names, yet a character pointer for band members? I'd expect something like char *name; char *members[20];
or char name[10]; char members[20][30];
– chux
Nov 7 at 23:16
Design question: why use a fixed array size
char name[10]
for band names, yet a character pointer for band members? I'd expect something like char *name; char *members[20];
or char name[10]; char members[20][30];
– chux
Nov 7 at 23:16
The first line is a syntax error
– M.M
Nov 7 at 23:20
The first line is a syntax error
– M.M
Nov 7 at 23:20
add a comment |
3 Answers
3
active
oldest
votes
up vote
1
down vote
accepted
You don't have a "two dimensional array". What you have is a simple array of struct band
which contains two simple character arrays as its members.
There is actually no need to compute the number of "members"
in each bands. All you need to compute is the number of bands
, e.g.
int nbands = sizeof bands / sizeof *bands;
Since you have declared members
as an array of pointers and have used an initializer to initialize the first four, the remaining pointers will have all bytes set 0
resulting in each being NULL
. You can simply loop for the members
with while (bands[i].members[j])
, incrementing j
each iteration, e.g.
#include <stdio.h>
struct band {
char name[10];
char *members[20];
};
int main(void) {
const struct band bands = {
{"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
int nbands = sizeof bands / sizeof *bands;
for (int i = 0; i < nbands; i++) {
int j = 0;
puts (bands[i].name);
while (j < 20 && bands[i].members[j])
printf (" %s", bands[i].members[j++]);
putchar ('n');
}
}
(note addition of j < 20
, which as pointed out by @chux in the comments, the test of while (bands[i].members[j])
alone could result in Undefined Behavior in the case where there were additional bands added bands
after initialization and all 20
pointers of the members
struct member were filled)
Example Use/Output
$ ./bin/bandmembers
Beatles
John George Paul Ringo Pete George
Stones
Mick Keith Bill Charlie Brian
Who
Pete Roger Keith John
JHE
Jimmy Noel Mitch
Additionally, don't use magic numbers in your code. Instead, If you need a constant, #define
one (or more), e.g.
#define MAXNM 10
#define MAXMB 20
or use a global enum
to do the same thing, e.g.
enum { MAXNM = 10, MAXMB = 20 };
That will allow you to eliminate the magic numbers, e.g.
struct band {
char name[MAXNM];
char *members[MAXMB];
};
This becomes very important for maintainability as your code length grows.
1
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybewhile (j < MAXMB && bands[i].members[j])
?
– chux
Nov 7 at 23:04
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
I don't think theMAXNM
andMAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use ofsizeof
avoids the possibility of errors due to code duplication
– M.M
Nov 7 at 23:22
@chux while the check forj < MAXMB
is a fine addition, the check as it sits iswhile (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)
– David C. Rankin
Nov 8 at 0:33
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
|
show 1 more comment
up vote
1
down vote
what I'm doing wrong
Wrong numMembers
calculation
numMembers
should be the number of elements in the array. (20)
Each bands[i].member
has 20 elements given char *members[20]
. Several elements are populated with pointers to string literals. Most elements remain 0 (NULL
).
// numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
numMembers = sizeof(bands[0].members) / sizeof(bands[0].members[0]);
Attempting to print NULL
as a string
printf ("t%s", bands[i].members[j]);
not valid when bands[i].members[j]
is NULL
.
Not all bands[i].members[j]
are set to a non-NULL
value.
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[i].members) / sizeof(bands[i].members[0]);
for ( j = 0; j < numMembers; ++j ) {
if (bands[i].members[j]) {
printf ("t%s", bands[i].members[j]);
}
}
printf ("n");
}
}
Deeper:
const struct band bands = { {"Beatles", ...
forms bands
and sizes bands
based on the number of initializers.
char *members[20];
is a fixed size even if the initialization did not supply 20 strings. The first elements members[20]
are initialized per the list, the remaining elements have a pointer value of 0.
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
add a comment |
up vote
0
down vote
For numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
sizeofband(bands[0]) will give the size of one band struct - that is the 10 bytes for name, and then 20 * the size of a pointer.
sizeof(bands[0].members); will give 20*thesizeof a pointer
Not what you want, as sizeof doesn't take into consideration the content of whatever the pointer points to.
It also doesn't take into consideration that some of those members pointers will be NULL so you don't want to count them.
Perhaps better doing:
for ( j = 0; j < 20 && bands[i].members[j] != NULL; ++j )
printf ("t%s", bands[i].members[j]);
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
add a comment |
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
accepted
You don't have a "two dimensional array". What you have is a simple array of struct band
which contains two simple character arrays as its members.
There is actually no need to compute the number of "members"
in each bands. All you need to compute is the number of bands
, e.g.
int nbands = sizeof bands / sizeof *bands;
Since you have declared members
as an array of pointers and have used an initializer to initialize the first four, the remaining pointers will have all bytes set 0
resulting in each being NULL
. You can simply loop for the members
with while (bands[i].members[j])
, incrementing j
each iteration, e.g.
#include <stdio.h>
struct band {
char name[10];
char *members[20];
};
int main(void) {
const struct band bands = {
{"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
int nbands = sizeof bands / sizeof *bands;
for (int i = 0; i < nbands; i++) {
int j = 0;
puts (bands[i].name);
while (j < 20 && bands[i].members[j])
printf (" %s", bands[i].members[j++]);
putchar ('n');
}
}
(note addition of j < 20
, which as pointed out by @chux in the comments, the test of while (bands[i].members[j])
alone could result in Undefined Behavior in the case where there were additional bands added bands
after initialization and all 20
pointers of the members
struct member were filled)
Example Use/Output
$ ./bin/bandmembers
Beatles
John George Paul Ringo Pete George
Stones
Mick Keith Bill Charlie Brian
Who
Pete Roger Keith John
JHE
Jimmy Noel Mitch
Additionally, don't use magic numbers in your code. Instead, If you need a constant, #define
one (or more), e.g.
#define MAXNM 10
#define MAXMB 20
or use a global enum
to do the same thing, e.g.
enum { MAXNM = 10, MAXMB = 20 };
That will allow you to eliminate the magic numbers, e.g.
struct band {
char name[MAXNM];
char *members[MAXMB];
};
This becomes very important for maintainability as your code length grows.
1
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybewhile (j < MAXMB && bands[i].members[j])
?
– chux
Nov 7 at 23:04
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
I don't think theMAXNM
andMAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use ofsizeof
avoids the possibility of errors due to code duplication
– M.M
Nov 7 at 23:22
@chux while the check forj < MAXMB
is a fine addition, the check as it sits iswhile (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)
– David C. Rankin
Nov 8 at 0:33
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
|
show 1 more comment
up vote
1
down vote
accepted
You don't have a "two dimensional array". What you have is a simple array of struct band
which contains two simple character arrays as its members.
There is actually no need to compute the number of "members"
in each bands. All you need to compute is the number of bands
, e.g.
int nbands = sizeof bands / sizeof *bands;
Since you have declared members
as an array of pointers and have used an initializer to initialize the first four, the remaining pointers will have all bytes set 0
resulting in each being NULL
. You can simply loop for the members
with while (bands[i].members[j])
, incrementing j
each iteration, e.g.
#include <stdio.h>
struct band {
char name[10];
char *members[20];
};
int main(void) {
const struct band bands = {
{"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
int nbands = sizeof bands / sizeof *bands;
for (int i = 0; i < nbands; i++) {
int j = 0;
puts (bands[i].name);
while (j < 20 && bands[i].members[j])
printf (" %s", bands[i].members[j++]);
putchar ('n');
}
}
(note addition of j < 20
, which as pointed out by @chux in the comments, the test of while (bands[i].members[j])
alone could result in Undefined Behavior in the case where there were additional bands added bands
after initialization and all 20
pointers of the members
struct member were filled)
Example Use/Output
$ ./bin/bandmembers
Beatles
John George Paul Ringo Pete George
Stones
Mick Keith Bill Charlie Brian
Who
Pete Roger Keith John
JHE
Jimmy Noel Mitch
Additionally, don't use magic numbers in your code. Instead, If you need a constant, #define
one (or more), e.g.
#define MAXNM 10
#define MAXMB 20
or use a global enum
to do the same thing, e.g.
enum { MAXNM = 10, MAXMB = 20 };
That will allow you to eliminate the magic numbers, e.g.
struct band {
char name[MAXNM];
char *members[MAXMB];
};
This becomes very important for maintainability as your code length grows.
1
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybewhile (j < MAXMB && bands[i].members[j])
?
– chux
Nov 7 at 23:04
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
I don't think theMAXNM
andMAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use ofsizeof
avoids the possibility of errors due to code duplication
– M.M
Nov 7 at 23:22
@chux while the check forj < MAXMB
is a fine addition, the check as it sits iswhile (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)
– David C. Rankin
Nov 8 at 0:33
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
|
show 1 more comment
up vote
1
down vote
accepted
up vote
1
down vote
accepted
You don't have a "two dimensional array". What you have is a simple array of struct band
which contains two simple character arrays as its members.
There is actually no need to compute the number of "members"
in each bands. All you need to compute is the number of bands
, e.g.
int nbands = sizeof bands / sizeof *bands;
Since you have declared members
as an array of pointers and have used an initializer to initialize the first four, the remaining pointers will have all bytes set 0
resulting in each being NULL
. You can simply loop for the members
with while (bands[i].members[j])
, incrementing j
each iteration, e.g.
#include <stdio.h>
struct band {
char name[10];
char *members[20];
};
int main(void) {
const struct band bands = {
{"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
int nbands = sizeof bands / sizeof *bands;
for (int i = 0; i < nbands; i++) {
int j = 0;
puts (bands[i].name);
while (j < 20 && bands[i].members[j])
printf (" %s", bands[i].members[j++]);
putchar ('n');
}
}
(note addition of j < 20
, which as pointed out by @chux in the comments, the test of while (bands[i].members[j])
alone could result in Undefined Behavior in the case where there were additional bands added bands
after initialization and all 20
pointers of the members
struct member were filled)
Example Use/Output
$ ./bin/bandmembers
Beatles
John George Paul Ringo Pete George
Stones
Mick Keith Bill Charlie Brian
Who
Pete Roger Keith John
JHE
Jimmy Noel Mitch
Additionally, don't use magic numbers in your code. Instead, If you need a constant, #define
one (or more), e.g.
#define MAXNM 10
#define MAXMB 20
or use a global enum
to do the same thing, e.g.
enum { MAXNM = 10, MAXMB = 20 };
That will allow you to eliminate the magic numbers, e.g.
struct band {
char name[MAXNM];
char *members[MAXMB];
};
This becomes very important for maintainability as your code length grows.
You don't have a "two dimensional array". What you have is a simple array of struct band
which contains two simple character arrays as its members.
There is actually no need to compute the number of "members"
in each bands. All you need to compute is the number of bands
, e.g.
int nbands = sizeof bands / sizeof *bands;
Since you have declared members
as an array of pointers and have used an initializer to initialize the first four, the remaining pointers will have all bytes set 0
resulting in each being NULL
. You can simply loop for the members
with while (bands[i].members[j])
, incrementing j
each iteration, e.g.
#include <stdio.h>
struct band {
char name[10];
char *members[20];
};
int main(void) {
const struct band bands = {
{"Beatles", {"John", "George", "Paul", "Ringo", "Pete", "George"} },
{"Stones", {"Mick", "Keith", "Bill", "Charlie", "Brian"} },
{"Who", {"Pete", "Roger", "Keith", "John"} },
{"JHE", {"Jimmy", "Noel", "Mitch"} } };
int nbands = sizeof bands / sizeof *bands;
for (int i = 0; i < nbands; i++) {
int j = 0;
puts (bands[i].name);
while (j < 20 && bands[i].members[j])
printf (" %s", bands[i].members[j++]);
putchar ('n');
}
}
(note addition of j < 20
, which as pointed out by @chux in the comments, the test of while (bands[i].members[j])
alone could result in Undefined Behavior in the case where there were additional bands added bands
after initialization and all 20
pointers of the members
struct member were filled)
Example Use/Output
$ ./bin/bandmembers
Beatles
John George Paul Ringo Pete George
Stones
Mick Keith Bill Charlie Brian
Who
Pete Roger Keith John
JHE
Jimmy Noel Mitch
Additionally, don't use magic numbers in your code. Instead, If you need a constant, #define
one (or more), e.g.
#define MAXNM 10
#define MAXMB 20
or use a global enum
to do the same thing, e.g.
enum { MAXNM = 10, MAXMB = 20 };
That will allow you to eliminate the magic numbers, e.g.
struct band {
char name[MAXNM];
char *members[MAXMB];
};
This becomes very important for maintainability as your code length grows.
edited Nov 8 at 0:54
answered Nov 7 at 22:26
David C. Rankin
39.2k32546
39.2k32546
1
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybewhile (j < MAXMB && bands[i].members[j])
?
– chux
Nov 7 at 23:04
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
I don't think theMAXNM
andMAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use ofsizeof
avoids the possibility of errors due to code duplication
– M.M
Nov 7 at 23:22
@chux while the check forj < MAXMB
is a fine addition, the check as it sits iswhile (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)
– David C. Rankin
Nov 8 at 0:33
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
|
show 1 more comment
1
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybewhile (j < MAXMB && bands[i].members[j])
?
– chux
Nov 7 at 23:04
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
I don't think theMAXNM
andMAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use ofsizeof
avoids the possibility of errors due to code duplication
– M.M
Nov 7 at 23:22
@chux while the check forj < MAXMB
is a fine addition, the check as it sits iswhile (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)
– David C. Rankin
Nov 8 at 0:33
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
1
1
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybe while (j < MAXMB && bands[i].members[j])
?– chux
Nov 7 at 23:04
while (bands[i].members[j]) printf (" %s", bands[i].members[j++]);
this is UB when the initialization had 20 band members. Maybe while (j < MAXMB && bands[i].members[j])
?– chux
Nov 7 at 23:04
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
David many thanks. Your points on magic numbers are noted.
– Griffau
Nov 7 at 23:05
I don't think the
MAXNM
and MAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use of sizeof
avoids the possibility of errors due to code duplication– M.M
Nov 7 at 23:22
I don't think the
MAXNM
and MAXNB
improve the code . It's obvious what the numbers mean in their original context, and the use of sizeof
avoids the possibility of errors due to code duplication– M.M
Nov 7 at 23:22
@chux while the check for
j < MAXMB
is a fine addition, the check as it sits is while (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)– David C. Rankin
Nov 8 at 0:33
@chux while the check for
j < MAXMB
is a fine addition, the check as it sits is while (bands[i].members[j] != NULL)
which is not UB based on the initialization rules. See § 6.7.9 Initialization (p10) and § 6.7.9 Initialization (p19)– David C. Rankin
Nov 8 at 0:33
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
@M.M agreed for this short snippet. The addition was to address future programming where the "code length grows". I try to address all points and what could become bad habits. Sometimes what seems obvious to veterans is useful information for those just learning.
– David C. Rankin
Nov 8 at 0:37
|
show 1 more comment
up vote
1
down vote
what I'm doing wrong
Wrong numMembers
calculation
numMembers
should be the number of elements in the array. (20)
Each bands[i].member
has 20 elements given char *members[20]
. Several elements are populated with pointers to string literals. Most elements remain 0 (NULL
).
// numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
numMembers = sizeof(bands[0].members) / sizeof(bands[0].members[0]);
Attempting to print NULL
as a string
printf ("t%s", bands[i].members[j]);
not valid when bands[i].members[j]
is NULL
.
Not all bands[i].members[j]
are set to a non-NULL
value.
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[i].members) / sizeof(bands[i].members[0]);
for ( j = 0; j < numMembers; ++j ) {
if (bands[i].members[j]) {
printf ("t%s", bands[i].members[j]);
}
}
printf ("n");
}
}
Deeper:
const struct band bands = { {"Beatles", ...
forms bands
and sizes bands
based on the number of initializers.
char *members[20];
is a fixed size even if the initialization did not supply 20 strings. The first elements members[20]
are initialized per the list, the remaining elements have a pointer value of 0.
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
add a comment |
up vote
1
down vote
what I'm doing wrong
Wrong numMembers
calculation
numMembers
should be the number of elements in the array. (20)
Each bands[i].member
has 20 elements given char *members[20]
. Several elements are populated with pointers to string literals. Most elements remain 0 (NULL
).
// numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
numMembers = sizeof(bands[0].members) / sizeof(bands[0].members[0]);
Attempting to print NULL
as a string
printf ("t%s", bands[i].members[j]);
not valid when bands[i].members[j]
is NULL
.
Not all bands[i].members[j]
are set to a non-NULL
value.
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[i].members) / sizeof(bands[i].members[0]);
for ( j = 0; j < numMembers; ++j ) {
if (bands[i].members[j]) {
printf ("t%s", bands[i].members[j]);
}
}
printf ("n");
}
}
Deeper:
const struct band bands = { {"Beatles", ...
forms bands
and sizes bands
based on the number of initializers.
char *members[20];
is a fixed size even if the initialization did not supply 20 strings. The first elements members[20]
are initialized per the list, the remaining elements have a pointer value of 0.
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
add a comment |
up vote
1
down vote
up vote
1
down vote
what I'm doing wrong
Wrong numMembers
calculation
numMembers
should be the number of elements in the array. (20)
Each bands[i].member
has 20 elements given char *members[20]
. Several elements are populated with pointers to string literals. Most elements remain 0 (NULL
).
// numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
numMembers = sizeof(bands[0].members) / sizeof(bands[0].members[0]);
Attempting to print NULL
as a string
printf ("t%s", bands[i].members[j]);
not valid when bands[i].members[j]
is NULL
.
Not all bands[i].members[j]
are set to a non-NULL
value.
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[i].members) / sizeof(bands[i].members[0]);
for ( j = 0; j < numMembers; ++j ) {
if (bands[i].members[j]) {
printf ("t%s", bands[i].members[j]);
}
}
printf ("n");
}
}
Deeper:
const struct band bands = { {"Beatles", ...
forms bands
and sizes bands
based on the number of initializers.
char *members[20];
is a fixed size even if the initialization did not supply 20 strings. The first elements members[20]
are initialized per the list, the remaining elements have a pointer value of 0.
what I'm doing wrong
Wrong numMembers
calculation
numMembers
should be the number of elements in the array. (20)
Each bands[i].member
has 20 elements given char *members[20]
. Several elements are populated with pointers to string literals. Most elements remain 0 (NULL
).
// numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
numMembers = sizeof(bands[0].members) / sizeof(bands[0].members[0]);
Attempting to print NULL
as a string
printf ("t%s", bands[i].members[j]);
not valid when bands[i].members[j]
is NULL
.
Not all bands[i].members[j]
are set to a non-NULL
value.
numBands = sizeof(bands) / sizeof(bands[0]);
for ( i = 0; i < numBands; ++i ) {
printf ("%sn", bands[i].name);
numMembers = sizeof(bands[i].members) / sizeof(bands[i].members[0]);
for ( j = 0; j < numMembers; ++j ) {
if (bands[i].members[j]) {
printf ("t%s", bands[i].members[j]);
}
}
printf ("n");
}
}
Deeper:
const struct band bands = { {"Beatles", ...
forms bands
and sizes bands
based on the number of initializers.
char *members[20];
is a fixed size even if the initialization did not supply 20 strings. The first elements members[20]
are initialized per the list, the remaining elements have a pointer value of 0.
edited Nov 7 at 22:20
answered Nov 7 at 22:01
chux
78.8k869145
78.8k869145
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
add a comment |
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
Chux many thanks for your input it is greatly appreciated.
– Griffau
Nov 7 at 23:07
add a comment |
up vote
0
down vote
For numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
sizeofband(bands[0]) will give the size of one band struct - that is the 10 bytes for name, and then 20 * the size of a pointer.
sizeof(bands[0].members); will give 20*thesizeof a pointer
Not what you want, as sizeof doesn't take into consideration the content of whatever the pointer points to.
It also doesn't take into consideration that some of those members pointers will be NULL so you don't want to count them.
Perhaps better doing:
for ( j = 0; j < 20 && bands[i].members[j] != NULL; ++j )
printf ("t%s", bands[i].members[j]);
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
add a comment |
up vote
0
down vote
For numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
sizeofband(bands[0]) will give the size of one band struct - that is the 10 bytes for name, and then 20 * the size of a pointer.
sizeof(bands[0].members); will give 20*thesizeof a pointer
Not what you want, as sizeof doesn't take into consideration the content of whatever the pointer points to.
It also doesn't take into consideration that some of those members pointers will be NULL so you don't want to count them.
Perhaps better doing:
for ( j = 0; j < 20 && bands[i].members[j] != NULL; ++j )
printf ("t%s", bands[i].members[j]);
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
add a comment |
up vote
0
down vote
up vote
0
down vote
For numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
sizeofband(bands[0]) will give the size of one band struct - that is the 10 bytes for name, and then 20 * the size of a pointer.
sizeof(bands[0].members); will give 20*thesizeof a pointer
Not what you want, as sizeof doesn't take into consideration the content of whatever the pointer points to.
It also doesn't take into consideration that some of those members pointers will be NULL so you don't want to count them.
Perhaps better doing:
for ( j = 0; j < 20 && bands[i].members[j] != NULL; ++j )
printf ("t%s", bands[i].members[j]);
For numMembers = sizeof(bands[0]) / sizeof(bands[0].members);
sizeofband(bands[0]) will give the size of one band struct - that is the 10 bytes for name, and then 20 * the size of a pointer.
sizeof(bands[0].members); will give 20*thesizeof a pointer
Not what you want, as sizeof doesn't take into consideration the content of whatever the pointer points to.
It also doesn't take into consideration that some of those members pointers will be NULL so you don't want to count them.
Perhaps better doing:
for ( j = 0; j < 20 && bands[i].members[j] != NULL; ++j )
printf ("t%s", bands[i].members[j]);
answered Nov 7 at 21:59
lostbard
2,7551311
2,7551311
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
add a comment |
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
@loastbard, many thanks for you help.
– Griffau
Nov 7 at 23:08
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53198424%2ftwo-dimensional-array-with-char-pointer-in-c%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Design question: why use a fixed array size
char name[10]
for band names, yet a character pointer for band members? I'd expect something likechar *name; char *members[20];
orchar name[10]; char members[20][30];
– chux
Nov 7 at 23:16
The first line is a syntax error
– M.M
Nov 7 at 23:20