I am creating a menu that needs to take in an three inputs from the users.
char *fullname;
char *date;
float sal;
printf("\nEnter full name: ");
line92
scanf("%s", &fullname);
printf("\nEnter hire date: ");
Line 94
scanf("%s", &date);
printf("\nEnter salary: ");
Line 96
scanf("%d", &sal);
These are the errors I am recieving
Employee.c:92: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
Employee.c:94: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char **’
Employee.c:96: warning: format ‘%d’ expects type ‘int *’, but argument 2 has type ‘float *’
Can I get an explanation of what is causing these issues?
There are several problems:
First:
When you use scanf for strings you do not use the &. So just scanf("%s", fullname);.
Second:
Your pointers aren't initialized. Try this instead:
char fullname[256];
char date[256];
This will work as long as you input at most 255 characters.
Third:
Your typing for the last scanf doesn't match. You're passing in a float when you've specified an int in the format string. Try this:
scanf("%f", &sal);
The warnings are pretty self-explanatory. When you call scanf with a %s format specifier you need to provide it a pointer to the first element of a char array where the string can be copied to. You're not doing that, instead you're giving it the address of a pointer to a char.
char[100] fullname;
scanf( "%s", fullname );
The same problem exists for date. Also, be aware that using the code above, a buffer overflow will occur if the user enters a string equal to or more than 100 characters in length.
If you're using MSVC you can use the scanf_s function instead that requires you to enter the length of the buffer. However, this function is Microsoft specific, hence, non-portable.
scanf_s( "%s", fullname, 100 );
For salary, the problem is that the format specifier is %d, which is used for reading ints, not floats. Use
scanf( "%f", &sal );
Related
#include<stdio.h>
#include<curses.h>
#include<string.h>
void main()
{ const char *str1[20];
const char *str2[20];
int comp;
printf("Enter the first string:\n");
scanf("%s",&str1);
printf("Enter the second string:\n");
scanf("%s",&str2);
comp=strcmp(str1,str2);
}
This was compiled in gcc compiler 4.8 . A detailed explanation will be appreciated.
Error message:
strcmp.c: In function ‘main’:
strcmp.c:10:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘const char * (*)[20]’ [-Wformat=]
scanf("%s",&str1);
^
strcmp.c:12:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘const char * (*)[20]’ [-Wformat=]
scanf("%s",&str2);
^
strcmp.c:13:14: warning: passing argument 1 of ‘strcmp’ from incompatible pointer type [-Wincompatible-pointer-types]
comp=strcmp(str1,str2);
^~~~
In file included from strcmp.c:3:0:
/usr/include/string.h:140:12: note: expected ‘const char *’ but argument is of type ‘const char **’
extern int strcmp (const char *__s1, const char *__s2)
^~~~~~
strcmp.c:13:19: warning: passing argument 2 of ‘strcmp’ from incompatible pointer type [-Wincompatible-pointer-types]
comp=strcmp(str1,str2);
^~~~
In file included from strcmp.c:3:0:
/usr/include/string.h:140:12: note: expected ‘const char *’ but argument is of type ‘const char **’
extern int strcmp (const char *__s1, const char *__s2)
const char *str1[20];
Should be
char str1[20];
You want a mutable array of characters, not an array of pointers.
scanf("%s",&str1);
Should be:
scanf("%s",str1);
The scanf function needs the address to store the input in. That's equivalent to &str1[0] which is what str1 decays into.
Your declared arrays are of the wrong type and qualifier.
The first thing is the incorrect declarations of the string buffers. You want an array of characters, but const char* str[20] declares an array of const character pointers (that is why the compiler is talking about argument 2 with type const char * (*)[20] being the wrong type). You do not want const here either since you want the characters to be changeable. char str[20] declares a string of characters which is what you really want.
Another point in C coding is that the address of an array is the same as the name of an array, so &str1 and str1 mean the same thing.
Change const char *str1[20]; to char str1[20];,
and scanf("%s",&str1); to scanf("%s",&str1[0]);
Same with second string.
As it currently is, you're declaring, not an array of characters, but an array of pointers to characters.
You're not printing any value, so hard to know the result of the comparison.
You did not explain exactly what your code is supposed to do, but I guess that
const char *str1[20];
(the above declares an array of 20 pointers to constant strings, or zones of several char-s)
should probably be
char str1[256];
this declares a single string -which should be writable by the computer, since you read it from thje user- of at most 256 bytes, and you want it to be null-terminated
(I'm using 256, because 80 bytes is really not a lot - and 20 bytes is not enough -; you want UTF8 everywhere, and 80 bytes can be much less than 80 characters).
BTW
scanf("%s",&str1);
is poor taste (may you wanted scanf("%19s", str1);). I suggest to use fgets and code:
if (!fgets(str1, sizeof(str1)-1, stdin)) {
perror("fgets str1");
exit(EXIT_FAILURE);
}
(Hint, you should always test for successful input).
BTW, always improve your code to get no warnings, and yes you need to compile with gcc -Wall -g (all warnings and debug info) to be able to use the gdb debugger (which you need to learn).
Why is this considered illegal in C ?
#include <stdio.h>
int main()
{
int integer;
char character;
float floatingPoint;
scanf(" %d %c %f", integer, character, floatingPoint);
return 0;
}
The above code produces the following error message under cc compiler.
cc Chapter2ex1.c
Chapter2ex1.c: In function ‘main’:
Chapter2ex1.c:8:5: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf(" %d%c%f", integer, character, floatingPoint);
^
Chapter2ex1.c:8:5: warning: format ‘%c’ expects argument of type ‘char *’, but argument 3 has type ‘int’ [-Wformat=]
Chapter2ex1.c:8:5: warning: format ‘%f’ expects argument of type ‘float *’, but argument 4 has type ‘double’ [-Wformat=]
You need to write
// v---------v-----------v-- addresses taken here
scanf(" %d %c %f", &integer, &character, &floatingPoint);
scanf needs to know the places where it should write the values it reads, not the values that currently reside there.
I'm creating a program using C, and I have this line in my code :
scanf("%s", &path);
When I compile the source file, I get this warning :
main.c:84:2: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[64]’ [-Wformat]
And this is the declaration for the path variable :
char path[64];
Why I'm seeing this error? And how can I solve it ?
An array is already a pointer-like object (as dreamlax points out). You don't need the & operator, since declaring
char path[64];
is equivalent to setting path to a pointer to a 64-byte region of memory.
The %s format specifier requires you to supply a char *, which is a pointer to char. You are passing &path, which is a pointer to an array. You can just pass path by itself, which will evaluate to a pointer to the first element of the array (the same as &path[0]).
try this scanf("%s", path); instead because I think path is an array and a pointer to an array is the array name itself ( array == &array )
I have this simple code in C to scan and print a string with a whitespace:
#include <stdio.h>
#include <string.h>
int main()
{
char myName[50];
printf("Enter your name: ");
scanf("%[^\n]s", &myName);
printf("Your name is: %s", myName);
return 0;
}
The compiler (gcc, part of the command line tools that come with Xcode on my mac) is returning this error:
name.c: In function ‘main’:
name.c:7: warning: format ‘%[^
’ expects type ‘char *’, but argument 2 has type ‘char (*)[50]’
name.c:7: warning: format ‘%[^
’ expects type ‘char *’, but argument 2 has type ‘char (*)[50]’
What's the problem here?
NOTE: I am required to use scanf. No fgets for me :(
You should pass to scanf argument of type char* (format %[^\n]s expects so), but in your code:
char myName[50];
scanf("%[^\n]s", &myName);
you pass an address of myName array (i.e. char (*)[50]). You should change it either to:
scanf("%[^\n]", myName);
or:
scanf("%[^\n]", &myName[0]);
What's the problem here?
Well, here it is:
format expects type ‘char *’, but argument has type ‘char (*)[50]’
A pointer to an array is not the same as a pointer to the first element of an array. You should get rid of that & operator.
Couple issues
Wrong scanf() format s. The s is not part of the format specifier. The %[] format specifier ends with the ].
Wrong scanf() parameter &myName. Rather than passing the address of &myName, which is type char (*)[50] , simply use myName. This will pass the address of the first element of myName which is a char *, the expected matching type for %[].
Use
scanf("%[^\n]", myName);
Further recommend to consume leading white space and limit text read. The 49 limits the input to 49 characters, leaving 1 more byte for the terminating \0.
scanf(" %49[^\n]", myName);
In C, myName (when passed to a function) decays to a pointer to the first element of array (myname) of characters. &myName is a pointer to the array myname. &myName[0] would be a pointer to the first character, which is correct, but looks like you tried stuff at random until you chanced on something that worked.
Your problem is that your are passing the address to the pointer of the start of the string, rather than the pointer to the string. Simply, remove the &.
scanf("%[^\n]", myName);
Beginner question. I have the following code:
char input[10];
scanf("%s", &input);
My compiler throws the following warning:
warning: format '%s' expects type 'char *', but argument 2 has type 'char (*)[10]'
warning: format '%s' expects type 'char *', but argument 2 has type 'char (*)[10]'
Changing to:
char * input;
Does not seem to help. What am I doing wrong?
Because an array already can be used as a pointer, so you don't need to the address-of operator.
If you read the warning message again, you will see that when you use the address-of operator on the array, you get a pointer to the array.
Try,
char input[10];
scanf("%s", input);
You don't have to give the address-of operator (&) with the name of the array input.
%s format string accepts argument of type char* where as &intput is of type char (*)[10] that is the reason you are getting warning.
format '%s' expects type 'char *', but argument 2 has type 'char (*)[10]
Note argument 2 is &input in scanf()
scanf("%s", &input);
^ ^
| argument-2
argument-1
To correct this code you should write scanf like:
scanf("%s", input);
Side note:: value wise both &input and input are same if you string address but semantically both are diffrent.
&input is address of array that is char(*) [10] type whereas input type is char[10]
To understand difference between &input and input read this two answers:
What does sizeof(&arr) returns? , and
Issue with pointer to character array C++
Edit:
Changing to: char *input will not help you instead it becomes undefined behavoiur unless and until you allocated memory to input
char input[10] is a character array.
input itself represents the base address of the array, i.e a char *.
You do not need to use the address of operator (&)with it. instead, use:
char input[10];
scanf("%s", input);
If you use char * input;, you need to allocate space for it using malloc. But in this case also, no need to use the address of operator.
scanf("%s", input);
you will get the answer.
char input[10];
scanf("%s", &input);
scanf requires the address to store the data that will be recieved. Array names already act like pointers, So you don't need the & operator to obtain the address.
format '%s' expects type 'char *', but argument 2 has type 'char (*)[10]'
When you do &input it indicates a pointer that is pointing to a char array of 10 char. char (*)[10]
input is itself char* and is only necessary to be passed as 2nd argument to scanf.
Go through this too for arrays and pointers.