445,918 Members | 2,240 Online
Need help? Post your question and get tips & solutions from a community of 445,918 IT Pros & Developers. It's quick & easy.

# A concatenation problem

 P: n/a The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); Nov 14 '05 #1
24 Replies

 P: n/a Caroline spoke thus: The following is not working Not really a surprise... int num = 0, char *string; string = "qwerty"; Fine and dandy, but... strcpy(string, num); ....what is this? The prototype for strcpy is char * strcpy( char * dst, const char * src ); What do you suppose happens when you pretend that num is a const char *? It certainly has a very low probability of doing anything useful. strcpy(string, ".png"); And likewise... string points to a string literal, which is not guaranteed to be modifiable. strcpy'ing to it is certainly a bad plan. -- Christopher Benson-Manica | I *should* know what I'm talking about - if I ataru(at)cyberspace.org | don't, I need to know. Flames welcome. Nov 14 '05 #2

 P: n/a "Caroline" wrote in message news:da**************************@posting.google.c om... The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); 1. Your string points to constant "qwerty". You cannot modify the contents of a constant string. 2. strcpy(string, num) does not conform to the prototype of the function strcpy(). It takes two pointers to char as arguments. You probably want sprintf() Nov 14 '05 #3

 P: n/a Caroline wrote: The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); Nor should it be, for several reasons. In your code, `string' points to a string literal ("qwerty"), which is not modifiable. The function strcpy() expects a (const) char * as its second argument, where you have provided, `num', an int. Even if your use had been correct, you'd be overwriting whatever `string' points to, which is evidently not what you want. Look up the function `sprintf()'. *That's* what you're looking for. HTH, --ag BTW - the identifier `string' is reserved for the implementation. -- -- Artie Gold -- Austin, Texas Nov 14 '05 #4

 P: n/a On 29 Dec 2003 08:21:41 -0800, pl***@letsdothatagain.com (Caroline) wrote: The following is not working int num = 0, char *string; string = "qwerty"; string points to a constant character array. strcpy(string, num); 1) num is an integer, and not elegable for copying to a string. 2) /if/ num were a character array, your strcpy() would attempt to alter a constant character array, which is a violation of the C rules, and would result in an error condition. strcpy(string, ".png"); If this didn't have the same flaw as above (#2), it would copy the string ".png" over top of the original contents of the array pointed to by string. -- Lew Pitcher IT Consultant, Enterprise Technology Solutions Toronto Dominion Bank Financial Group (Opinions expressed are my own, not my employers') Nov 14 '05 #5

 P: n/a "Caroline" wrote in message news:da**************************@posting.google.c om... The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); Besides all of the errors that have already been pointed out by everyone else, you are also using strcpy() where you mean to use strcat(). Sean Nov 14 '05 #6

 P: n/a Le*********@td.com (Lew Pitcher) writes: On 29 Dec 2003 08:21:41 -0800, pl***@letsdothatagain.com (Caroline) wrote:The following is not working int num = 0, char *string; string = "qwerty"; string points to a constant character array. strcpy(string, num); 1) num is an integer, and not elegable for copying to a string. 2) /if/ num were a character array, your strcpy() would attempt to alter a constant character array, which is a violation of the C rules, and would result in an error condition. Strictly speaking, the character array isn't *necessarily* constant, but you should always assume that it is. Attempting to modify it causes undefined behavior (which, in the worst case, can look like behaving just the way you want it to). In my opinion, the language would be cleaner if it did define the array to be constant, requiring a diagnostic if you attempt to modify it, but the authors of the standard had to allow for existing implementations that allow (the array allocated for) a string literal to be modified. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> Schroedinger does Shakespeare: "To be *and* not to be" (Note new e-mail address) Nov 14 '05 #7

 P: n/a "Sean Kenwrick" writes: "Caroline" wrote in message news:da**************************@posting.google.c om... The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); Besides all of the errors that have already been pointed out by everyone else, you are also using strcpy() where you mean to use strcat(). And if you could write to the array, and corrected the strcpy() to strcat(), you'd still be writing past the end of the array. -- Keith Thompson (The_Other_Keith) ks***@mib.org San Diego Supercomputer Center <*> Schroedinger does Shakespeare: "To be *and* not to be" (Note new e-mail address) Nov 14 '05 #8

 P: n/a Concatenating a string with an int with strcat is painful. sprinf(string, "%*c%d", strlen(string), string, num); should do it, right? Greets. Nov 14 '05 #9

 P: n/a "stau" wrote in message news:pa****************************@pretogal.pt... Concatenating a string with an int with strcat is painful. sprinf(string, "%*c%d", strlen(string), string, num); should do it, right? In what context? But let's have a look at your line again: sprinf(string, "%*c%d", strlen(string), string, num); For the moment, I assume that string is declared as char *, num as int and that stdio.h and string.h are #included... 1. What is sprinf? I suppose you mean sprintf. 2. * in %*c expects an int in the parameter list. And what it gets? A size_t. 3. c in %*c expects a char in the parameter list. And what iy gets? A char *. 4. * in %*c specifies the width; if you mean what I think you mean, it has no effect here Using my crystal ball (beware, it may be broken!), I think that what you want is something like this: #include int main (void) { char filename[115]; /* Or suitably wide enough */ int number; /* Assign number, let's say... */ number = 42; sprintf(filename, "%s%d.%s", "prefix", number, "ext"); /* Use filename */ return 0; } Peter Nov 14 '05 #10

 P: n/a stau wrote: Concatenating a string with an int with strcat is painful. Please quote some context so we know what you are talking about. sprinf(string, "%*c%d", strlen(string), string, num); should do it, right? No way to know, without knowing something about what sprinf is. If you meant sprintf, then no. string still points to something that is not modifiable. Even if it where, there's not enough space for the resulting string. If those were fixed, this would still be broken. At a purely syntactic level, you have supplied incorrect types for the first 2 arguments. The '*' tells it to expect an int, but you provide a size_t. %c expects an int, but you provide a char *. As for the logic, it's completely wrong. %c prints a single character, not a string. The width specifier just adds spaces. It's not clear whether strlen(string) would be useful or well-defined when 'string' is the destination buffer (depends on whether it contains anything useful initially). I doubt sprintf() is well-defined when the destination buffer is also used as a source. -Kevin -- My email address is valid, but changes periodically. To contact me please use the address from a recent posting. Nov 14 '05 #11

 P: n/a Peter Pichler wrote: 3. c in %*c expects a char in the parameter list. And what iy gets? A char *. Actually it expects an int, which is converted to unsigned char. 4. * in %*c specifies the width; if you mean what I think you mean, it has no effect here Except that it will add spaces on the left if the provided width is more than the number of characters to be printed (1 in this case). Using my crystal ball (beware, it may be broken!), I think that what you want is something like this: #include int main (void) { char filename[115]; /* Or suitably wide enough */ int number; /* Assign number, let's say... */ number = 42; sprintf(filename, "%s%d.%s", "prefix", number, "ext"); You *could* do it something like this: char *filename; /* ... */ filename = malloc(strlen(prefix) + strlen(ext) + (sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1); if (filename != NULL) sprintf(filename, "%s%d.%s", prefix, number, ext); assuming 'prefix' and 'ext' are strings. That way you'd be sure to have enough space (if I got the calculation right). -Kevin -- My email address is valid, but changes periodically. To contact me please use the address from a recent posting. Nov 14 '05 #12

 P: n/a On Mon, 29 Dec 2003 22:30:37 +0000, stau wrote in comp.lang.c: Concatenating a string with an int with strcat is painful. sprinf(string, "%*c%d", strlen(string), string, num); should do it, right? Greets. Assuming that you meant "sprintf"... Absolutely not, even is string points to a large enough array of writable characters. If there is an overlap between the destination buffer passed to sprintf() and any source string, you produce undefined behavior. -- Jack Klein Home: http://JK-Technology.Com FAQs for comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html comp.lang.c++ http://www.parashift.com/c++-faq-lite/ alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq Nov 14 '05 #13

 P: n/a Caroline wrote: The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); Define "working". It certainly won't compile, and even if wrapped in a main and some #includes it won't run. -- Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net) Available for consulting/temporary embedded and systems. USE worldnet address! Nov 14 '05 #14

 P: n/a stau writes: Concatenating a string with an int with strcat is painful. sprinf(string, "%*c%d", strlen(string), string, num); should do it, right? No, for reasons that others have satisfactorily explained. However, the following will append a %d-formatted int to `string': sprintf (strchr (string, '\0'), "%d", num); -- int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\ \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\ );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\ );}return 0;} Nov 14 '05 #15

 P: n/a On 29 Dec 2003 08:21:41 -0800, pl***@letsdothatagain.com (Caroline) wrote: The following is not working Be thankful. int num = 0, char *string; string = "qwerty"; string now points to the memory occupied by the string literal. strcpy(string, num); This attempts to copy data to the area pointed to by string. Attempting to modify a string literal invokes undefined behavior. You apparently did not #include string.h. If you had, your compiler would have told you the second argument is invalid because strcpy requires a char* and you used an int. Assuming your compiler "did you a favor" and generated the code to convert the int to a pointer, num has the value 0 so the pointer would have the value NULL. Attempting to dereference a NULL pointer invokes undefined behavior. strcpy(string, ".png"); Had this worked, it would have overlaid the data copied in the previous statement. Did you perhaps mean strcat to be consistent with the title of your message? It still would invoke undefined behavior but at least it would have done so while attempting to concatenate the new data with the old. <> Nov 14 '05 #16

 P: n/a On Mon, 29 Dec 2003 23:41:31 +0000, Kevin Goodsell wrote: Peter Pichler wrote: You *could* do it something like this: char *filename; /* ... */ filename = malloc(strlen(prefix) + strlen(ext) + (sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ god, what's this? Thanks. Nov 14 '05 #17

 P: n/a "Keith Thompson" wrote in message news:ln************@nuthaus.mib.org... "Sean Kenwrick" writes: "Caroline" wrote in message news:da**************************@posting.google.c om... The following is not working int num = 0, char *string; string = "qwerty"; strcpy(string, num); strcpy(string, ".png"); Besides all of the errors that have already been pointed out by everyone else, you are also using strcpy() where you mean to use strcat(). And if you could write to the array, and corrected the strcpy() to strcat(), you'd still be writing past the end of the array. I did say 'besides all the errors that have been pointed out by everyone else'. There were about 10 other posts all pointing out the obvious flaws in this code, but no-one had yet spotted that the OP was using strcpy() instead of strcat() - which according to the subject of the post is whart they were trying to do.... Sean Nov 14 '05 #18

 P: n/a On Tue, 30 Dec 2003 08:57:20 +0000, stau wrote: On Mon, 29 Dec 2003 23:41:31 +0000, Kevin Goodsell wrote: Peter Pichler wrote: You *could* do it something like this: char *filename; /* ... */ filename = malloc(strlen(prefix) + strlen(ext) + (sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^god, what's this? Isn't it a (crude) worst case estimate of the maximum length needed to hold the string representation of any possible integer? How big does ch[] need to be for sprintf(ch, "%d", INT_MIN) to never overflow? <> Nov 14 '05 #19

 P: n/a Barry Schwarz wrote: On Tue, 30 Dec 2003 08:57:20 +0000, stau wrote:On Mon, 29 Dec 2003 23:41:31 +0000, Kevin Goodsell wrote:Peter Pichler wrote:You *could* do it something like this:char *filename;/* ... */filename = malloc(strlen(prefix) + strlen(ext) + (sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^god, what's this? Isn't it a (crude) worst case estimate of the maximum length needed to hold the string representation of any possible integer? How big does ch[] need to be for sprintf(ch, "%d", INT_MIN) to never overflow? That is what the expression represents (though the two '+ 1's should also be included - one reserves space for the null terminating character, the other for a possible negative/minus sign). The expression is taken from the FAQ for this group. You should be able, with a bit of effort, to derive it yourself. The key point is that it determines the maximum number of *octal* digits (and other characters) needed for an int. The number of decimal (or hexadecimal) digits needed is guaranteed to be no more than the number of octal digits needed. -Kevin -- My email address is valid, but changes periodically. To contact me please use the address from a recent posting. Nov 14 '05 #20

 P: n/a On Tue, 30 Dec 2003 08:57:20 +0000 stau wrote: On Mon, 29 Dec 2003 23:41:31 +0000, Kevin Goodsell wrote: Peter Pichler wrote: You *could* do it something like this: char *filename; /* ... */ filename = malloc(strlen(prefix) + strlen(ext) + (sizeof(int) * CHAR_BIT + 2) / 3 + 1 + 1); ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ god, what's this? An overestimate of the number of characters required to print an integer. sizeof(int) * CHAR_BIT == the number of bits used to store an integer With 3 bits you can represent integers 0-7, so assuming 3 bits per printed digit is a slight overestimate. +2 before dividing by 3 so make sure any odd bits count as a digit to be printed. -- Flash Gordon Paid to be a Geek & a Senior Software Developer Although my email address says spam, it is real and I read it. Nov 14 '05 #21

 P: n/a Thank you all for your help. The following gave me the result I wanted on the first iteration: char *nameOfFile; char *ext ; char *prefix; sprintf(nameOfFile, "%s%d.%s", prefix, Comp, ext); "Peter Pichler" wrote in message news:<3f**********@mk-nntp-2.news.uk.tiscali.com>... ... Using my crystal ball (beware, it may be broken!), I think that what you want is something like this: #include int main (void) { char filename[115]; /* Or suitably wide enough */ int number; /* Assign number, let's say... */ number = 42; sprintf(filename, "%s%d.%s", "prefix", number, "ext"); /* Use filename */ return 0; } Peter Nov 14 '05 #22

 P: n/a Thank you all for your help. The following gave me the result I wanted on the first iteration: char *nameOfFile; char *ext ; char *prefix; nameOfFile =""; sprintf(nameOfFile, "%s%d.%s", prefix, SomeNumber, ext); .... but when I the function executed again, similar results appeared. 1 - How can I reset the variables at each iteration? 2 - How (and why) would MALLOC be used in this case? "Peter Pichler" wrote in message news:<3f**********@mk-nntp-2.news.uk.tiscali.com>... ... Using my crystal ball (beware, it may be broken!), I think that what you want is something like this: #include int main (void) { char filename[115]; /* Or suitably wide enough */ int number; /* Assign number, let's say... */ number = 42; sprintf(filename, "%s%d.%s", "prefix", number, "ext"); /* Use filename */ return 0; } Peter Nov 14 '05 #23