问题
Say I have an array
char messages[10][2][50];
What is the correct syntax for strcpy, in order to get the data into one of the strings (inner most char array of size 50) and then the corresponding convention to supply it to printf via %s?
For that matter, am I declaring the array subscripts in the correct order? It is intended to be 10 lots of, pairs (of 2) strings. Each string being 50 chars wide.
01{{50 chars},{50 chars}}
02{{50 chars},{50 chars}}
...
09{{50 chars},{50 chars}}
10{{50 chars},{50 chars}}
Various internet sources seem to conflict on which subscript to omit and, whatever I try seems to produce unintended results.
e.g. Could you fill in the blanks to the following
strcpy(message???, "Message 1 Part 1");
strcpy(message???, "m1 p2");
strcpy(message???, "m2 p1");
strcpy(message???, "m2 p2");
strcpy(message???, "m3 p1");
strcpy(message???, "m3 p1");
//So on...
int i;
for(i=0;i<10;i++)
printf("%s, %s\n", message???, message???);
Such that the array has a structure of and holds:
01{{"Message 1 Part 1\0"},{"m1 p2\0"}}
02{{"m2 p1\0"},{"m2 p2\0"}}
01{{"m3 p1\0"},{"m3 p2\0"}}
//So on...
And outputs as such
Message 1 part 1, m2 p2
m2, p2
m3, p3
and so on
回答1:
I just wrote a quick program to show the things you've asked about... loading them up at declaration, strncpy into one of them, and then printing them out.
Hope it helps
edit: I kind of hate magic numbers so I almost totally removed them
edit: I've added alternatives Tommi Kyntola and I were talking about in the comments
#include <stdio.h>
#include <string.h>
// safe string copy macro, terminates string at end if necessary
// note: could probably just set the last char to \0 in all cases
// safely if intending to just cut off the end of the string like this
#define sstrcpy(buf, src, size) strncpy(buf, src, size); if(strlen(src) >= size) buf[size-1] = '\0';
#define MSGLIMIT 10
#define MSGLENGTH 30
#define MSGFIELDS 2
#define MSGNAME 0
#define MSGTEXT 1
int main(void) {
char messages[MSGLIMIT][MSGFIELDS][MSGLENGTH] = { {"bla", "raa"},
{"foo", "bar"}
};
int i;
char *name1 = "name16789012345678901234567890";
char *text1 = "text16789012345678901234567890";
char *name2 = "name26789012345678901234567890";
char *text2 = "text26789012345678901234567890";
char *name3 = "name36789012345678901234567890";
char *text3 = "text36789012345678901234567890";
// doesn't set last char to \0 because str overruns buffer
// undocumented result of running this, but likely to just get the name2 string
// as that'll be the very next thing in memory on most systems
strncpy(messages[2][MSGNAME], name1, MSGLENGTH); // 2 because it's the next empty one
strncpy(messages[2][MSGTEXT], text1, MSGLENGTH);
// alternative suggested by Tommi Kyntola
// printf family are more complicated and so cost more cpu time than strncpy
// but it's quick and easy anywhere you have string.h and fine most of the time
snprintf(messages[3][MSGNAME], MSGLENGTH, "%s", name2);
snprintf(messages[3][MSGTEXT], MSGLENGTH, "%s", text2);
// uses the define macro at the top of the page to set the last char to \0 if
// otherwise not set by strncpy, adds a little weight but still the better option
// if performance of this section of code is important
sstrcpy(messages[4][MSGNAME], name3, MSGLENGTH);
sstrcpy(messages[4][MSGTEXT], text3, MSGLENGTH);
for(i = 0; i < 5; i++) // 5 because that's how many I've populated
printf("%s : %s\n", messages[i][MSGNAME], messages[i][MSGTEXT]);
return 0;
}
回答2:
You can ommit greatest subscription(in you ex. it is 10), as it can be calculated by compiler according to remained subscriptions. To pass layers of 50 elements use pointers: (*messages)[10][2] - will be pointer on layer of 50 elements
回答3:
I would use:
assuming you want to copy to char* new_buff
memcpy(new_buff, messages, 10*2*50);
you can do a 3 nested loop and use strncpy
.
don't use strcpy... it is unsecured
回答4:
As has been pointed out, best to use strncpy, or as in my example below, use asserts, to prevent possible buffer overruns. There's a tiny increase in performance in strcpy vs strncpy.
#define FIRST_OF_PAIR 0
#define SECOND_OF_PAIR 1
int message_num = 7;
char messages[10][2][50];
char *string = "hello";
assert(strlen(string) < 50);
assert(message_num > 0 && message_num < 10);
strcpy(messages[message_num][SECOND_OF_PAIR], "Hello");
printf("%s", messages[message_num][SECOND_OF_PAIR]);
回答5:
It will be
strcpy(message[0][0], "Message 1 Part 1");
strcpy(message[0][1], "m1 p2");
strcpy(message[2][0], "m2 p1");
strcpy(message[2][1], "m2 p2");
strcpy(message[3][0], "m3 p1");
strcpy(message[3][1], "m3 p2");
for(i=0;i<10;i++)
printf("%s, %s\n", message[i][0], message[i][1]);
try to get the concept.
来源:https://stackoverflow.com/questions/12051187/strcpy-and-printf-a-multidimensional-char-array-c