error: conflicting types for 'removeSpaces' - c

I want to write a program which will verify whether the string is palindrome or not.
But there is an error when I try to pass strings[0] to removeSpaces function which will remove spaces.
Why does 'comflicting types error' occurs? What is wrong?
The whole code of programm:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char * removeSpaces(char *); // prototype
int main()
{
char *strings[2]; // created array of pointers
strings[0] = strdup("a man a plan a canal panama");
printf("%s\n", strings[0]);
strings[1] = removeSpaces(strings[0]);
printf("%s\n", strings[0]);
/* (in future) it will display "amanaplanacanalpanama" */
free(strings[0]);
return 0;
}
char * removeSpaces(char * str[0]) // an ERROR occurs here
{
/* some code */
return -1; // in case of fault
}

Your code has two issues:
Your function declaration and definition conflicted. You don't have to specify
char *str[0], char *str is enough and it should match with your declaration at the top.
You are returning -1 instead of a pointer which is not a valid pointer in its form. If some fault occurs I would recommend you to return NULL instead.
-1 is an integer. But however, you can also use 0 instead, because that defaults to (void *)0 nothing but NULL.
change like this:
char * removeSpaces(char * str) // an ERROR occurs here
{
/* some code */
return NULL; // return NULL in case of fault instead of -1
}

When you declare a function, each parameter needs a type and a name. Your removeSpaces function takes a single parameter of type char *, so you'd declare it as
char * removeSpaces(char * str)
Remember, the function doesn't know that you'll be passing it the first element of an array; it just knows you'll give it a pointer to a string of characters.
It's also the convention in C to return a null pointer when its data is missing or would be invalid. So instead of returning -1 if there's an error, you should return NULL.

The declaration:
char * removeSpaces(char *);
Is different from the definition:
char * removeSpaces(char * str[0]);
Change the prototype:
char * removeSpaces(char *);

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

C literals, where are these stored

Consider the following code:
#include <stdio.h>
void f(const char * str) {
str = "java";
}
void main (int argc, char * argv[]) {
const char *str = "erlang";
f(str);
printf("%s\n", str);
}
The output is "erlang" and I don't quite know why..
My current knowledge says that string literals "erlang" and "java" are both stored in the process adress space, within section "constants". And according to this, the fucntion f should change the pointer to point to "java", but this doesn't happen. Could someone please explain what is going on here?
Because function arguments are passed by value in C and modifying arguments in callee won't affece caller's local variables.
Use pointers to modify caller's local variables.
#include <stdio.h>
void f(const char ** str) { /* add * to declare pointer */
*str = "java"; /* add * to access what is pointed */
}
int main (int argc, char * argv[]) { /* use standard signature */
const char *str = "erlang";
f(&str); /* add & to get a pointer pointing at str */
printf("%s\n", str);
}
C has copy by value. When str is passed as an argument to f, it is copied first, and that very copy is actually passed to f. Assigning "java" to that copy doesn't do anything to the original str in main.
Since you are passing the value that means call by value you will see the output as java if you pass the reference like this:
#include <stdio.h>
void f(const char ** str) {
*str = "java";
}
void main (int argc, char * argv[]) {
const char *str = "erlang";
f(&str);
printf("%s\n", str);
}
output:
rabi#rabi-VirtualBox:~/rabi/c$ gcc ptr1.c
rabi#rabi-VirtualBox:~/rabi/c$ ./a.out
java
Function parameters are its local variables. You can imagine the function definition and its call the following way (I changed the name of the parameter from str to s for clearity)
void f(/*const char * s*/) {
const char *s = str;
s = "java";
}
//...
const char *str = "erlang";
f(str);
Any changes of the local variable s does not influence on the original variable str used as the argument. The variable str itself was unchanged.
You should pass arguments by reference if you are going to change them in a function. For example
#include <stdio.h>
void f( const char ** str )
{
*str = "java";
}
int main( void )
{
const char *str = "erlang";
f( &str );
printf( "%s\n", str );
}
The program output is
java
Take into account that according to the C Standard function main shall have return type int.
Could someone please explain what is going on here?
Many good answers all ready yet thought I'd try to perform a detailed walk-though with OP with slightly modified code.
Consider what happens with f("Hello World"). "Hello World" is a string literal. It initializes a char array. When an array is passed to a function or assigned to a pointer, it is converted to the address of the first element of the array. f() receives a copy of the address of 'H' in its str. #1 prints "Hello World". str is re-assigned to the address of 'j'. #2 prints "java". The function ends without affecting "Hello World".
With str = "erlang", str receives the address of the 'e'. #3 prints "erlang". On the function call, the value of main()'s str is copied to the f()'s str. #1 prints "erlang". Like before, str is re-assigned to the address of 'j'. #2 prints "java". The function ends without affecting main()'s str. #4 prints "erlang".
#include <stdio.h>
void f(const char * str) {
printf("f() before str='%s'\n", str); // #1
str = "java";
printf("f() after str='%s'\n", str); // #2
}
int main(void) {
f("Hello World");
puts("");
const char *str = "erlang";
printf("main() before str='%s'\n", str); // #3
f(str);
printf("main() after str='%s'\n", str); // #4
return 0;
}
Output
f() before str='Hello World'
f() after str='java'
main() before str='erlang'
f() before str='erlang'
f() after str='java'
main() after str='erlang'
As to OP's question:
C literals, where are these stored?
The location of a string literal is not defined in C. It might use the "process address space, within section constants", it might not. What is important is that an array is formed and the address of the first character is given in assignment to a const char *. Further detail: writing to this address is undefined behavior (UB), it may "work", fail, seg-fault, etc.
This would be more obvious if you changed the name of the argument for f...
#include <stdio.h>
void f(const char * foo) {
foo = "java";
}
int main (int argc, char * argv[]) {
const char *str = "erlang";
f(str);
printf("%s\n", str);
}
foo is a different variable to str. It has a different name, a different scope, and can contain a different value. The changes to foo won't propagate to str. If you wanted to modify str from within f, you would need to make f look like this:
void f(const char **foo) {
*foo = "java";
}
... and pass a pointer to str to f like so: f(&str);.
Did you happen to notice how I changed void main to int main? There are only two signatures for main entry points (excluding the equivalents) that are guaranteed by the standard to be portable:
int main(void) { /* ... */ }
... and ...
int main(int argc, char *argv[]) { /* ... */ }
Either way, main always returns int (or equivalent). This shouldn't inconvenience you too much, as in C99 (any half-decent compiler that's newer than fifteen years old) and C11 there's this little gem which allows you to omit return 0; from main:
If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0.
So if anything, your code using an int main entry point is not just portable but also one byte shorter than your code using a non-portable void main entry point.

C - passing argument 1 of 'send_data' makes pointer from integer without a cast

Im writing uart code for a microcontroller. My code is working fine with passing string("..."), but giving problem when i try to passing the char('.'). Yes, it is i've declared "s" a pointer for string, but there is a chance of passing char value. Is there any possibilities to pass both string and char values in send_data?
#include <stdio.h>
void send_data( char *s)
{
while(*s!='\0')
{
send_dt1(*s);
s++;
}
}
void send_dt1( char in_c)
{
printf("%c",in_c);
}
int main(void)
{
send_data("sample_data"); //fine
send_data('Q'); //warning, no data displaying
return 0; /* terminate the program */
}
Thanks..
As send_data expects s to be a null-terminated string anyway, I would just recommend using a string:
send_data("Q");
Notes:
you should pass a const char* around as long as you don't modify the string at s
send_data('Q'); //warning, no data displaying
Don't pass character to it . It expects a char * .
You can do this -
send_data("Q");
Also you should declare a prototype for function void send_dt1( char in_c) as you make a call to it before it's definition in function void send_data( char *s) .
This will also generate warning.
You can't pass a char to a function that expects a char *.
If you really need to be able to pass both, you'll need another function to accept a char and put it in a string so that send_data can be called:
void send_char_data(char c)
{
char s[2];
s[0] = c;
s[1] = '\0';
send_data(s);
}
....
int main(void)
{
send_data("sample_data");
send_char_data('Q');
return 0;
}

pointers in c (beginner)

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.

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