pointers in c (beginner) - c

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.

Related

Why I have error: deprecated conversion from string constant to 'char*' [-Wwrite-strings] in the line 5 and 6?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
char *preorden="GEAIBMCLDFKJH";//line 5
error in the above line
char *inorden="IABEGLDCFMKHJ";//line 6
error in this line
char *postorden;
error in this line
void post(char *pre, char *in, char *pos,int n)
{
int longIzqda;
if(n!=0){
pos[n-1]=pre[0];
longIzqda=strchr(in,pre[0])-in;
post (pre+1,in,pos,longIzqda);
post (pre+1+longIzqda,in+1+longIzqda,pos+longIzqda,n-1-longIzqda);
}
}
int main(int argc,char *argv[])
{
int aux;
aux=strlen(preorden);//convert to string
postorden=(char *)malloc(aux*sizeof(char));//use of malloc function
if (postorden){
printf("The preorden is: %s\n",preorden);
printf("The inorden is: %s\n",inorden);
post(preorden,inorden,postorden,aux);
postorden[aux]='\0';
printf("The postorden calculated is: %s\n",postorden);
free(postorden);
}
else{
fprintf(stderr,"Whithout memory\n");
return 1; // return 1
}
return 0;
}
the error is in the line 5 and 6
the compiler says:
deprecated conversion from string constant to 'char*' [-Wwrite-strings]
There are few issues with your code, firstly this
char *preorden="GEAIBMCLDFKJH";//line 5
forces compiler to warn you like below if compiled with -Wwrite-strings flags in C
deprecated conversion from string constant to 'char*'
[-Wwrite-strings]
because the string literal GEAIBMCLDFKJH stored in read only section of primary memory i.e pointer where it points, that contents is read only, hence instead of char* use const char*. for e.g
char *preorden = "GEAIBMCLDFKJH";/* preorden is normal pointer but "GEAIBMCLDFKJH" is read only, hence error */
And
const char *preorden = "GEAIBMCLDFKJH"; /* const char *ptr means ptr contents is read only */
Secondly, here
postorden=(char *)malloc(aux*sizeof(char));//use of malloc function
casting of malloc result is not required as malloc() return type is void* which is automatically and safely promoted to any other pointer type, Read Do I cast the result of malloc?. for e.g
postorden = malloc(aux * sizeof(*postorden));//use of malloc function
Also here(this point is about wrong comment on below line, please don't mind)
aux=strlen(preorden);//convert to string
strlen(preorden) returns the length of string pointed by preorden and gets assigned to aux not as written in comments(convert to string).
And change the post() definition to
void post(const char *pre, const char *in, char *pos,int n) {
/* some code*/
}
The message “deprecated conversion from string constant to 'char*' [-Wwrite-strings]” arises because the code was compiled as C++ code, which has different rules about string literals and pointer conversions from C.
This can be fixed by compiling the code as C code or worked around by inserting an explicit cast to char *.

Use of strcmp, initialization makes pointer from integer without a cast

void check_vertical_win(char A[rows][columns]){
int i,j;
char *str1=A[i][j];
char *str2=A[i-1][j];
char *str3=A[i-2][j];
char *str4=A[i-3][j];
int elegxos1;
int elegxos2;
elegxos1=strcmp(str1,str2);
elegxos2=strcmp(str3,str4);
for(j=0;j<6;j++){
for(i=6;i>=3;i--){
if(elegxos1==0 && elegxos2==0){
printf("\nBill is the winner.\n");
}
}
}
}
I want to check if two strings in a matrix are equal,so i'm using the function strcmp. However the compiler gives warning: Initialization makes pointer from integer without a cast.
(Then when i run the programme it says: Windows are checking for a solution at my problem).
I've tried a lot to find my mistake looking other similar programmes but i can't find out.
void check_vertical_win(char A[rows][columns])
This takes a matrix of chars. If you have a matrix where each entry is a string, it should be:
void check_vertical_win(char* A[rows][columns])
Also, you're using variables i and j before they are initialized (they contain garbage):
int i,j;
char *str1=A[i][j];
char *str2=A[i-1][j];
char *str3=A[i-2][j];
char *str4=A[i-3][j];

usage of strdup

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *s;
s = strdup("foo");
printf("%s\n", s);
getchar();
return 0;
}
Looks pretty harmless, doesn't it ?
But my IDE, which is Dev-C++, gives my the following warning:
warning: assignment makes pointer from integer without a cast
The warning disappears if you would change the code like this:
char *s;
s = (char*)strdup("foo");
Can anyone help me explain this?
You're using Dev-C++, but strdup is not part of the C or C++ standard, it's a POSIX function. You need to define the proper (according to your IDE's documentation) preprocessor symbols in order for strdup to be declared by the header file ... this is necessary in order for the header file not to pollute the name space when included into conforming C or C++ source files.
For a simple portable alternative, consider
char* mystrdup(const char* s)
{
char* p = malloc(strlen(s)+1);
if (p) strcpy(p, s);
return p;
}
Or, if you know strdup is actually in the library, you can copy its declaration from string.h into your own source file or header ... or use the simpler declaration from the man page:
char *strdup(const char *s);
That's not right. strdup returns char * already. Something else is wrong. Probably because you did not include the right header file that declares the true return type for this function.
#include <string.h>
You're missing #include <string.h>. In the absence of function signatures, strdup is assumed by the compiler to return an int, hence the warning.
man strdup
you will get following things
#include<string.h>
char* strdup(const char * s);
so strdup() returns char* there shuld not be any problem
Actually in your case it takes implicit declaration of strdup() so by default return type is int hence you get this warning
Either include<string.h>
or
give forward declaration char* strdup(const char *);
Also don't forget to free(s) in last when all usage are done

c pass a string to function then return a string

#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *abc = "abc";
char *new_str;
new_str = getStr(&abc);
printf("%s", abc);
}
char *getStr(char *str)
{
printf(str);
return str;
}
What's wrong with the code above?
A bunch of small things:
You're passing &abc to getStr(). &abc is a pointer to the variable that is holding your string. Its type a pointer to a pointer, and that's incompatible with the char *str argument of getStr().
Your getStr() is defined after it is used. You either need to move its definition to before main() or add a prototype before main().
The type of a string literal like "abc" is const char *. You're defining a variable of type char *, which is dubious (since it would allow you to modify a string literal, which is not allowed).
here is a working version:
#include <stdio.h>
#include <stdlib.h>
char *getStr(char *str);
int main(void)
{
char *abc = "abc";
char *new_str;
new_str = getStr(abc);
//printf("%s", *abc); don't really need this
}
char *getStr(char *str) {
printf("%s", str);
return str;
}
Here's a list of problems with the old one:
No prototype for your function getStr.
You can't do printf(str) you need a "%s" as an additional param.
You need to change: new_str = getStr(&abc) to new_str = getStr(abc)
A C string is a pointer to a character that begins a sequence of characters that end with a null byte. The variable abc perfectly fits this definition.
Also, abc is of type pointer to character. You are passing the address of abc, ie getStr will be receiving the address of a pointer to a character--so getStr's only argument should be of type pointer to pointer to character. The types do not match up.
EDIT: Also, getStr is called before it's declared. Your compiler may allow this, but it's bad practice for many reasons. You should declare it or define it before it is used. If you are using gcc as your compiler, always use
gcc -ansi -Wall -pedantic
Those three flags will conform to ANSI standards, and it would either yell at you for the above issues or not compile.
Your getStr function takes a char *, but that's not what you're passing it - you're passing the address of the pointer, instead of passing it the actual pointer.
Change:
new_str = getStr(&abc);
to:
new_str = getStr(abc);
and I think it'll work.

Cannot return and assign char array to pointer in C

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;
}

Resources