c - Do I need check destination string length using strcat inside a for loop -
char command [][12] = { {"attention!!"}, {"about turn!"}, {"left turn!"}, {"right turn!"}, {"dismiss!"} }; int i; (i=1; i<5; i++) { strcat (command [0], command [i]); } printf ("length of command[0]:%ld\nnew string:%s\n", strlen(command[0]), command[0]);
in above block of code, need check destination string command[0]
see if has enough space other 4 strings?
i didn't turns out compiler didn' t report error , printed out concatenated string.
is ok loop?
yes, need consider space available in target string when using strcat()
. in fact, need consider available space string manipulation operations. if don't know there enough space, not safe.
consider array:
char command[][12] = { {"attention!!"}, {"about turn!"}, {"left turn!"}, {"right turn!"}, {"dismiss!"} };
the memory array looks this, using $
represent '\0'
+---+---+---+---+---+---+---+---+---+---+---+---+ | | t | t | e | n | t | | o | n | ! | ! | $ | +---+---+---+---+---+---+---+---+---+---+---+---+ | | b | o | u | t | | t | u | r | n | ! | $ | +---+---+---+---+---+---+---+---+---+---+---+---+ | l | e | f | t | | t | u | r | n | ! | $ | $ | +---+---+---+---+---+---+---+---+---+---+---+---+ | r | | g | h | t | | t | u | r | n | ! | $ | +---+---+---+---+---+---+---+---+---+---+---+---+ | d | | s | m | | s | s | ! | $ | $ | $ | $ | +---+---+---+---+---+---+---+---+---+---+---+---+
the specification of strcat()
says:
the
strcat
function appends copy of string pointeds2
(including terminating null character) end of string pointeds1
. initial character ofs2
overwrites null character @ end ofs1
. if copying takes place between objects overlap, behavior undefined.
your processing loop is:
for (int = 1; < 5; i++) { strcat(command[0], command[i]); }
it clear invoking undefined behaviour because extended material in command[0]
runs on content of command[1]
. nevertheless, common implementations behave sensibly, there no guarantee every implementation will.
indeed, when run on macos sierra 10.12.2 gcc 6.3.0, first iteration of loop generates abort trap: 6
error. legitimate result of 'undefined behaviour'.
however, if 'reimplement' strcat()
behave might expect, end is:
+---+---+---+---+---+---+---+---+---+---+---+---+ | | t | t | e | n | t | | o | n | ! | ! | | +---+---+---+---+---+---+---+---+---+---+---+---+ | b | o | u | t | | t | u | r | n | ! | l | e | +---+---+---+---+---+---+---+---+---+---+---+---+ | f | t | | t | u | r | n | ! | r | | g | h | +---+---+---+---+---+---+---+---+---+---+---+---+ | t | | t | u | r | n | ! | d | | s | m | | +---+---+---+---+---+---+---+---+---+---+---+---+ | s | s | ! | $ | | s | s | ! | $ | $ | $ | $ | +---+---+---+---+---+---+---+---+---+---+---+---+
demonstration code
#include <ctype.h> #include <stdio.h> #include <string.h> static inline void n_strcat(char *s1, char *s2) { memmove(s1 + strlen(s1), s2, strlen(s2) + 1); } #ifndef use_real_strcat #undef strcat #define strcat(s1, s2) n_strcat(s1, s2) #endif /* use_real_strcat */ static void print_bar(int cols) { printf(" +"); (int = 0; < cols; i++) printf("---+"); putchar('\n'); } static void print_cmd(int rows, int cols, char cmd[rows][cols]) { print_bar(cols); (int = 0; < rows; i++) { printf(" |"); (int j = 0; j < cols; j++) { unsigned char u = cmd[i][j]; if (!isprint(u)) u = '$'; printf(" %c |", u); } putchar('\n'); print_bar(cols); } } int main(void) { char command[][12] = { { "attention!!" }, { "about turn!" }, { "left turn!" }, { "right turn!" }, { "dismiss!" }, }; enum { cmd_rows = sizeof(command) / sizeof(command[0]) }; enum { cmd_cols = sizeof(command[0]) / sizeof(command[0][0]) }; print_cmd(cmd_rows, cmd_cols, command); (int = 1; < 5; i++) strcat(command[0], command[i]); printf("\nlength of command[0]: %zu\nnew string: [%s]\n\n", strlen(command[0]), command[0]); print_cmd(cmd_rows, cmd_cols, command); return 0; }
the output program 2 tables shown above, information in between:
length of command[0]: 51 new string: [attention!!about turn!left turn!right turn!dismiss!]
Comments
Post a Comment