A concatenation problem

C

Caroline

The following is not working

int num = 0,
char *string;

string = "qwerty";
strcpy(string, num);
strcpy(string, ".png");
 
I

Isaac Mushinsky

Caroline said:
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()
 
C

Christopher Benson-Manica

Caroline said:
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.
 
A

Arthur Gold

Caroline said:
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.
 
L

Lew Pitcher

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')
 
S

Sean Kenwrick

Caroline said:
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
 
S

stau

Concatenating a string with an int with strcat is painful.

sprinf(string, "%*c%d", strlen(string), string, num);

should do it, right?

Greets.
 
K

Keith Thompson

string points to a constant character array.


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.
 
K

Keith Thompson

Sean Kenwrick said:
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.
 
P

Peter Pichler

stau said:
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 <stdio.h>

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
 
K

Kevin Goodsell

stau said:
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
 
K

Kevin Goodsell

Peter said:
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 <stdio.h>

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
 
J

Jack Klein

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
 
C

CBFalconer

Caroline said:
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.
 
B

Ben Pfaff

stau said:
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);
 
B

Barry Schwarz

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.



<<Remove the del for email>>
 
S

stau

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.
 
S

Sean Kenwrick

Keith Thompson said:
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
 
F

Flash Gordon

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
 
B

Barry Schwarz

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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?


<<Remove the del for email>>
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,129
Messages
2,570,770
Members
47,329
Latest member
FidelRauch

Latest Threads

Top