By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
435,009 Members | 2,859 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 435,009 IT Pros & Developers. It's quick & easy.

Question on arrays within a struct and sprintf

P: n/a
aap
I have the following code
#define MAX 32
struct A
{
char carr[MAX];
int iarr[MAX];
int i;
};
void main()
{
struct A a;
strcpy(a.carr, "a.carr Test1");
char test[MAX];
strcpy(test, "2Test2");
sprintf(test, "%s", &a.carr); //method1
printf("%s\n", test);
sprintf(test, "%s", a.carr); //method2
printf("%s\n", test);
}
I use sprintf twice. In the first case I pass &a.carr as the argument
and in the second caseI pass a.carr as the argument.
In both the cases, the code works just fine.
Why does it not fail in the first case?
How come &a.carr and a.carr both produce identical results?

I apologize if this is already covered in a faq.

Thanks.

Nov 15 '05 #1
Share this Question
Share on Google+
2 Replies


P: n/a


aap wrote:
I have the following code
#define MAX 32
struct A
{
char carr[MAX];
int iarr[MAX];
int i;
};
void main()
{
struct A a;
strcpy(a.carr, "a.carr Test1");
char test[MAX];
strcpy(test, "2Test2");
sprintf(test, "%s", &a.carr); //method1
printf("%s\n", test);
sprintf(test, "%s", a.carr); //method2
printf("%s\n", test);
}
I use sprintf twice. In the first case I pass &a.carr as the argument
and in the second caseI pass a.carr as the argument.
In both the cases, the code works just fine.
Why does it not fail in the first case?
How come &a.carr and a.carr both produce identical results?

I apologize if this is already covered in a faq.


It's sort of covered by Questions 6.12 and 6.12 in
the comp.lang.c FAQ list

http://www.eskimo.com/~scs/C-faq/top.html

Check them out, and ask again if it's still not clear.
(While you're at it, see Question 11.2 as well.)

--
Er*********@sun.com

Nov 15 '05 #2

P: n/a
"aap" <ap*****@gmail.com> writes:
I have the following code
#define MAX 32
struct A
{
char carr[MAX];
int iarr[MAX];
int i;
};
void main()
{
struct A a;
strcpy(a.carr, "a.carr Test1");
char test[MAX];
strcpy(test, "2Test2");
sprintf(test, "%s", &a.carr); //method1
printf("%s\n", test);
sprintf(test, "%s", a.carr); //method2
printf("%s\n", test);
}
I use sprintf twice. In the first case I pass &a.carr as the argument
and in the second caseI pass a.carr as the argument.
In both the cases, the code works just fine.
Why does it not fail in the first case?
How come &a.carr and a.carr both produce identical results?

I apologize if this is already covered in a faq.


The C FAQ is at <http://www.eskimo.com/~scs/C-faq/top.html>.
Section 6 is probably most relevant to your problem (but read
the whole thing).

main() returns int, not void. The correct declaration (if you're not
using command-line arguments) is "int main(void)". This isn't likely
to cause visible problems in practice, but there's no reason not to do
it right. Once you fix that, you should have a "return 0;" at the end
of main (not required in C99, and not strictly required in C90, but a
good idea).

You're mixing declarations and statements in main(). This is
permitted in C99, but not in C90. (It's also permitted in C++, but
that's irrelevant unless you're using a C++ compiler.)

You need a "#include <stdio.h>" to use sprintf and printf, and a
"#include <string.h>" to use strcpy.

Your problem really has nothing to do with structures. Here's a
simplified example.

#include <stdio.h>
#include <string.h>

#define MAX 32

int main(void)
{
char target[MAX];
char source[] = "hello";
sprintf(target, "%s", source); /* ok */
printf("target = \"%s\"\n", target);
sprintf(target, "%s", &source); /* potential problem */
printf("target = \"%s\"\n", target);
return 0;
}

As you'll see when you've read section 6 of the FAQ, an array name is
implicitly converted to a pointer to its first element *unless* it's
the operand of a sizeof or unary "&" operator.

The first call to sprintf is ok. The "%s" format expects a char*
argument, and source is converted to type char* (a pointer to the
character 'h').

The second sprintf call is questionable. Because it's the operand of
a unary "&", source it's not converted to char*. The result of the
expression &source is the address of the array, not the address of its
first element. It is (in some sense) the same value, but of a
different type; it's a pointer-to-array-of-6-char rather than a
pointer-to-char.

On many, probably most, implementations, the two pointer types have
the same representation, and passing them to sprintf() will have the
same effect. But the standard doesn't guarantee this, and the call
actually invokes undefined behavior. That's the insidious thing about
undefined behavior; it can behave exactly as you expect (until the
most inconvenient possible moment for it to fail).

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
We must do something. This is something. Therefore, we must do this.
Nov 15 '05 #3

This discussion thread is closed

Replies have been disabled for this discussion.