aap said:
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).