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 pointed s2 (including terminating null character) end of string pointed s1. initial character of s2 overwrites null character @ end of s1. 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

Popular posts from this blog

javascript - Using jquery append to add option values into a select element not working -

Android soft keyboard reverts to default keyboard on orientation change -

Rendering JButton to get the JCheckBox behavior in a JTable by using images does not update my table -