Consider the following program:
#include <stdio.h>
void foo(char** string)
{
printf("%s", string[0]);
}
int main()
{
char* a = "blahblah";
foo(&a);
return 0;
}
It works fine as it is, but if I substitute
char* a = "blahblah";
with
char a[] = "blahblah";
it does not work.
I get the warning expected 'char **' but argument is of type 'char (*)[9]', and a segmentation fault.
I was under the impression that char[] and char* are the same thing, so a pointer to each of them would also be the same.
(windows with mingw, gcc 4.8.1)
Thank you
In most cases these two statements behave the same, with two exceptions. One exception is when applying the & operator. When you apply & to an array(e.g. a[]), you got the address of the whole array. This value is identical to the address of the first element of the array, so &a == a (their types are different tough). You can try a simple example here: http://ideone.com/96w3oa
Ok. Now we can see why you got a segmentation fault. Because &a is equal to a, your string[0] actually does an extra deference. The correct way would be:
printf("%s", string);
or
printf("%s", (&string)[0]);
if you use
char a[] = "blahblah";
For more information regarding the difference between the two statements you tried, please refer to this post (especially the post by John Bode): What is the difference between char s[] and char *s?.
Here is also a very good explanation:
http://publications.gbdirect.co.uk/c_book/chapter5/arrays_and_address_of.html
When you are passing the array to the foo function, you should do in this manner.
#include<stdio.h>
void display(char *);
int main()
{
char arr[]="Do something";
display(arr);
return 0;
}
void display(char *string)
{
printf("%s",string);
}
else you might be getting segmentation error.while using &array_name, you actually pass the address of the starting element.
Related
I am trying to return a string from str function but it prints (null)
#include<stdio.h>
char* str()
{
char hi[10] = "return this";
return hi;
}
void main()
{
printf("%s", str());
}
read static variables or global variables to access the variable outside the functions
there is an overflow in your code, read buffer overflow in c
Also read What should main() return in C and C++?
#include<stdio.h>
char* str()
{
static char hi[] = "return this";
return hi;
}
int main()
{
printf("%s", str());
return 0;
}
In GCC at least your code compiles with teh following warnings:
main.c:12:19: warning: initializer-string for array of chars is too long
main.c:13:12: warning: function returns address of local variable [-Wreturn-local-addr]
Which more or less is a direct answer to your question. If you did not get these warnings, consider the compiler switched you are using, for GCC I suggest at least -Wall -Werror - that will output the most useful warnings without being pedantic, and make those warnings errors so will prevent successful compilation until you fix them.
You are returning a pointer to a local-automatic variable that is no longer in scope after the function returns, so the result is undefined. You have also tried to initialise an array with more characters that you have reserved.
What the compiler has done here is given the invalid initialiser, it has set the address of hi to null, and printf has handles the null pointer by printing (null). That is behaviour specific to your compiler and C library - in other cases something different may happen. More insidious that that is that if your initialiser was not invalid (by being shorter), it is likely to have appeared to work and you might never have asked the question, but it would still be incorrect, and in more complex code would likely at some point cause observable erroneous behaviour.
In this particular case you could do any of the following:
const char* str()
{
static const char* hi = "return this";
return hi;
}
const char* str()
{
static const char hi[] = "return this";
return hi;
}
char* str( char* str, int maxlen )
{
str[maxlen] = '\0' ;
return strncpy( str, "return this", maxlen - 1 ) ;
}
void main()
{
char* buffer[32] ;
printf("%s", str(buffer, sizeof(buffer));
}
The most appropriate solution (and the above are by no means exhaustive) depend on what you actually want to do, since each solution differs semantically, and on its own this function is hardly practical. It would need a concrete real-world example to give best advice.
The problem is with the scope of the character array.
The solution for this issue is to make the address of that variable visible to the caller function!
i.e.
one of the easiest solutions is use the below line in the declaration part of hi variable in your str() function.
i.e.
static char hi[10] = "return th";
in the declaration.
This way you wouldn't need to change anything in this program BUT in the whole program, this variable WILL BE visible/accessible throughout the execution.
#include"stdio.h"
char* str() {
static char hi[10] = "return th";
return hi;
}
int main() {
printf("%s", str());
return 0;
}
#include<stdio.h>
#include<stdlib.h>
char* str(){
//malloc is used to allocate memory
char *hi=(char*)malloc(sizeof(char)*20);
char ch[]="return this\0";
for(int i=0;i<sizeof(ch);i++)
hi[i]=ch[i];
return hi;
}
int main(){
printf("%s", str());
return 0;
}
you can find more about malloc and sizeof operator.
I just returned to develop in C over eclipse and im having big issues im not sure how to solve, dont remember i used to have such when developing before. anyway i'll point u to 2 issues (i made my example easy-to-post in here):
#include <stdio.h>
int change_array(char *str, char *a[]) {
a[0] = "changed [0]";
if (fgets(str, 200, stdin) != NULL) {
}
return 0;
}
int main() {
char str[200];
char a[15][200];
change_array(str, a);
printf("a[0]: %s\n", a[0]);
printf("str: %s\n", str);
return 0;
}
getting a warning in line "change_array(str, a)": passing argument 2 of ‘change_array’ from incompatible pointer type [enabled by default] - why??
after running my 'doing-nothing' code sample output is:
some-value
a[0]: � <------- wired characters appear
str: some-value
The issue is here... int change_array(char *str, char *a[])
The dimension of a is undefined, so it doesn't know how far to step each *a and a is an array of pointers to char. However, you are passing in an array of arrays of 200 char. Thus the incompatible types error.
I believe your issue goes away with...
int change_array(char *str, char (*a)[200])
in which case a is a pointer to an array of 200 chars and the compiler now knows how far to step each index of a
I'm learning C today. I've been coding in managed languages (Java, C#, Python, etc.) for some time now. I thought I was understanding the details of pointers, but then I wrote the following code that worked as expected, but generated an 'incompatible pointer type' warning.
void setText(char* output) {
//code to set output to whatever, no problems here.
}
int main(int argc, const char* argv[]) {
char output[10];
setText(&output);
//[EDITED] ...other test code which printf's and further manipulates output.
return 0;
}
So I googled, and ended up changing the line
setText(&output);
to
setText(output);
which got rid of the warning. But now I don't know why the first one was working at all. I was sending the address of an address as far as I can tell (because char* x; is essentially the same as char x[];). What am I misunderstanding and why do both of these work?
The type of output is char [10], which decays to a char * in the context of a function call (which is why the second variant works).
The type of &output is char (*)[10], i.e. a pointer-to-array. This is not the same thing, hence the compiler warning. However, the value of &output (an address) is equivalent to the value of output (once it has decayed to a char *), so the end result is "as expected".
This may sound like pedantry, but there is a fairly important difference. Try the following:
void foo(const char *p)
{
printf("%s\n", p);
}
int main(void)
{
char output[][6] = { "Hello", "world" };
foo(output[0] + 1);
foo(&output[0] + 1);
}
Recommended reading is the C FAQ on arrays and pointers, in particular question 6.3 and 6.12.
I just started to look at C, coming from a java background. I'm having a difficult time wrapping my head around pointers. In theory I feel like I get it but as soon as I try to use them or follow a program that's using them I get lost pretty quickly. I was trying to follow a string concat exercise but it wasnt working so I stripped it down to some basic pointer practice. It complies with a warning conflicting types for strcat function and when I run it, crashes completly.
Thanks for any help
#include <stdio.h>
#include <stdlib.h>
/* strcat: concatenate t to end of s; s must be big enough */
void strcat(char *string, char *attach);
int main(){
char one[10]="test";
char two[10]="co";
char *s;
char *t;
s=one;
t=two;
strcat(s,t);
}
void strcat(char *s, char *t) {
printf("%s",*s);
}
Your printf() should look like this:
printf("%s",s);
The asterisk is unnecessary. The %s format argument means that the argument should be a char*, which is what s is. Prefixing s with * does an extra invalid indirection.
You get the warning about conflicting types because strchr is a standard library routine, which should have this signature:
char * strcat ( char * destination, const char * source );
Yours has a different return type. You should probably rename yours to mystrchr or something else to avoid the conflict with the standard library (you may get linker errors if you use the same name).
Change
printf("%s",*s);
to
printf("%s",s);
The reason for this is printf is expecting a replacement for %s to be a pointer. It will dereference it internally to get the value.
Since you declared s as a char pointer (char *s), the type of s in your function will be just that, a pointer to a char. So you can just pass that pointer directly into printf.
In C, when you dereference a pointer, you get the value pointed to by the pointer. In this case, you get the first character pointed to by s. The correct usage should be:
printf( "%s", s );
BTW, strcat is a standard function that returns a pointer to a character array. Why make your own?
Replacing *s with s won't append strings yet, here is fully working code :
Pay attention to function urstrcat
#include <stdio.h>
#include <stdlib.h>
/* urstrcat: concatenate t to end of s; s must be big enough */
void urstrcat(char *string, char *attach);
int main(){
char one[10]="test";
char two[10]="co";
char *s;
char *t;
s=one;
t=two;
urstrcat(s,t);
return 0;
}
void urstrcat(char *s, char *t) {
printf("%s%s",s,t);
}
pointers are variable which points to address of a variable.
#include "stdio.h"
void main(){
int a,*b;
a=10;
b=&a;
printf("%d",b);
}
in the follwing code you will see a int 'a' and a pointer 'b'.
here b is taken as pointer of an integer and declared by giving'' before it.'' declare that 'b' is an pointer.then you will see "b=&a".this means b is taking address of integer "a" which is keeping value 10 in that particular memory and printf is printing that value.
char *test = "hello";
test = change_test("world");
printf("%s",test);
char* change_test(char *n){
printf("change: %s",n);
return n;
}
im trying to pass a 'string' back to a char pointer using a function but get the following error:
assignment makes pointer from integer without a cast
what am i doing wrong?
A function used without forward declaration will be considered having signature int (...). You should either forward-declare it:
char* change_test(char*);
...
char* test = "hello";
// etc.
or just move the definition change_test before where you call it.
printf() prints the text to the console but does not change n. Use this code instead:
char *change_test(char *n) {
char *result = new char[256];
sprintf(result, "change: %s", n);
return result;
}
// Do not forget to call delete[] on the value returned from change_test
Also add the declaration of change_test() before calling it:
char *change_test(char *n);
You're converting an integer to a pointer somewhere. Your code is incomplete, but at a guess I'd say it's that you're not defining change_test() before you use it, so the C compiler guesses at its type (and assumes it returns an integer.) Declare change_test() before calling it, like so:
char *change_test(char *n);
thanks a bunch guys! didnt think i would have this problem solved by lunch. here is the final test class
/* standard libraries */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* change_test(char*);
int main(){
char *test = "hello";
test = change_test("world");
printf("%s",test);
return (EXIT_SUCCESS);
}
char* change_test(char *n){
return n;
}