This question already has answers here:
SegFault after scanf?
(4 answers)
Closed 6 years ago.
As per what I know, %d expects an int value. I don't understand why gcc compiler is saying that it expects int* instead.
Here is my code:
#include<stdio.h>
#include<stdlib.h>
struct student
{
int rn, m[5];
char nm[25];
};
int main()
{
struct student* s[5];
struct student **q=s;
int i = 0;
printf("Enter data");
for(i=0;i<5;i++)
{
printf("\nStudent %d:\n",i+1);
printf("Roll number: ");
scanf("%d",(s[i])->rn);
printf("\n%d",s[i]->rn);
}
}
And here is the warning:
warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
scanf("%d",(s[i])->rn);
scanf reads a value into an int, it takes an pointer to the variable to read into.
scanf("%d",&((s[i])->rn));
printf takes an int for %d, but scanf takes the address of an int (an int *) so it can store the converted value.
RTFM would help here. scanf and related functions (sscanf etc) always need pointers of the variable(s) to which they'll read the values to. scanf documentation
Related
#include <stdio.h>
int main(void)
{
int i,j,k;
char st;
printf("enter string\n");
scanf("%s", st);
printf("the entered string is %s\n", st);
}
Compiling above program gives me a warning:
warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
palindrom.c:8:1: warning: format '%s' expects argument of type 'char *', but argument 2 has type 'int' [-Wformat]
What am I doing wrong here?
This is what happens when I run it:
$ ./a.out
enter string
kiaaa
the entered string is (null)
Edit:
Here is another version of the code (made char st; into char *st):
#include <stdio.h>
int main(void)
{
int i,j,k;
char *st;
printf("enter string\n");
scanf("%s", st);
printf("the entered string is %s\n", st);
}
However, it behaves the same on runtime.
char st is a single character. Judging by the rest of your code, you probably intended to declare an array of characters:
char st[80];
scanf needs a pointer to char* to indicate you are scanning a string.
You are supplying a character that's allocated on the stack.
You either want to use a getchar() or make st a char array.
You have a type mis-match.
scanfis not type safe, You need to provide proper type. scanf enables you to get data from the input and you need to tell it what is the type of the data you want it to read. You ask it to read a string by specifying %s by provide it with a character variable.
You need an array:
#define MAX_LENGTH 256
char st[MAX_LENGTH];
As #Jerry rightly points out, You can just simple avoid all the hassle by using:
getline() instead of using scanf
st is type of char
&st is type of char *
Take care of the difference.
BTW, only one char cannot be used to store a string. Use char[] array.
As others have mentioned you want to create an array:
Change char st; to char st[10]; or whatever size array you want.
With the above change st is an array that has 10 individual elements that can hold a single char value.
char st is a character i.e it will store only one character try it like this
main()
char st [100];
scanf("%s",st);
just change these three lines and it will work it will except only single word strings
here you have declared the function as an int that is int main() keep it as main() and it will work
Use char *st; or an array like char st[50];.
When you complete the usage of a char pointer, you should deallocate the memory used by the pointer. This can be done using free(st); function.
EDIT : As you are printing string and if you are using pointer, you can do:
printf("the entered string is %s\n",st);
printf("the entered string is %s\n",*st); // This will work in both cases, if you use char *st or char st[50]
This question already has answers here:
When should I use ampersand with scanf()
(3 answers)
Closed 2 years ago.
My code is very simple just basic IO. Now when I use this code it works perfectly.
#include <stdio.h>
int main()
{
int age = 0;
char name[100]; //Unlike c++ We need to specify char limit instead of "Name", so name can't go above 99 char + 1 terinator
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your name: ");
scanf("%s", name);// dont need & for char
printf("Your name is %s and your age is %d\n", name, age);
return 0;
}
Now
#include <stdio.h>
int main()
{
int age = 0;
char name[100]; //Unlike c++ We need to specify char limit instead of "Name", so name can't go above 99 char + 1 terinator
printf("Enter your age: ");
scanf("%d", &age);
printf("Enter your name: ");
scanf("%s", &name);// dont need & for char
printf("Your name is %s and your age is %d\n", name, age);
return 0;
}
when I make changes in line 10. and add &name. compiler throws this error. Why is that?
p2.c:10:17: error: format specifies type 'char *' but the argument has type 'char (*)[100]' [-Werror,-Wformat]
scanf("%s", &name);// dont need & for char
~~ ^~~~~
I don't know much about C.
Strings in C are simply sequences of characters. The %s format specifier thus expects a pointer to char such that it can write whatever scanf reads into the character sequence at the memory location pointed to by that pointer. In your case name is a character array and not a pointer, but in C you can often use arrays in contexts where pointers are expected, we say that the array decays to a pointer to its first member.
The scanf function takes a pointer of the variable whose value is to be set.
For other types like int, we use & operator which specifies the address of the variable whereas for char[] the variable name is converted to the pointer to the first element of the array so we don't need a &.
Strings are arrays of chars. Arrays are passed by reference in C.
So when you pass array to the function you actually pass the pointer.
This question already has answers here:
format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[64]
(3 answers)
Closed 5 years ago.
I don't know how to fix this warning, but especially why it appears in my code. In the first phase, my code has to record some names and surname and I used structures.
#include <stdio.h>
typedef struct STUDENT{
char surname[50];
char name[50];
} student;
int main()
{
student a[30];
int aux;
int i,j,n;
printf("Number of students: ");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("Surname:");
scanf("%s",&a[i].surname);
printf("Name:");
scanf("%s",&a[i].name);
}
return 0;
}
&a[i].surname is actually giving the address of struct member array surname. surname is of type char [50] so it's address will be of type char (*)[50]. As an argument to a function, array decay to pointer to it's first element. So, a[i].surname will do the job. You need to remove & from the argument.
printf("Surname:");
scanf("%s",a[i].surname);
printf("Name:");
scanf("%s",a[i].name);
Do not use & in strings as surname is already in format scanf is expecting it.
printf("Surname:");
scanf("%s",a[i].surname);
printf("Name:");
scanf("%s",a[i].name);
Also, please read why you have to set length for string in scanf.
Read a string as an input using scanf
scanf is looking for a pointer to char, but in your code you've got this
scanf("%s",&a[i].name);
a[i].name is an array of char which for the purposes of scanf is the same as a char *, but you're getting the pointer to it, so you end up with char (*)[50]. Just remove the unneeded ampersand and you'll remove the warning and fix your code.
I am trying to understand why this code works
#include<stdio.h>
struct identity {
int age;
char name[20];
} test;
int main(void) {
printf("Enter name: ");
scanf("%s", &test.name);
printf("Enter age: ");
scanf("%d", &test.age);
printf("NAME: %s", test.name);
printf("\nAGE: %d", test.age);
}
even if I define the struct this way:
struct identity {
int *age;
char *name[20];
} test;
No matter how I write it, it works. I can understand that it works this way, but why does it work if I use the pointers?I mean, shouldn't it require printf("NAME: %s", *test.name); and printf("\nAGE: %d", *test.age); so as to print the value held inside the address of test.name and test.age respectively?
Is this a wrong way to use pointers within a struct? Therefore it works because I actually don't use pointers?
Its because when you put * your age works as an array, and char name[20] works as 2D array. In C when you have some array[] or array2d[][] when you put somewhere array it is your first element array[0] and when you put array2d it is your first poem (array[0][]). You also can do *(array+1) and this is the same like array[1].
It occurs to me that an int will fit in the space of an int *, on today's computers, so you can put the int value in the address space of the int var, without corrupting the other values of the struct. I added this to main():
printf("\nsizeof int: %d", (int) sizeof(int));
printf("\nsizeof int*: %d", (int) sizeof(int *));
and got this output on my system:
sizeof int: 4
sizeof int*: 8
Seems to me that's why it's working when the pointer vars are used instead of vars themselves?
Like many other questions, if you paid attention to compiler warnings, it'd be clear to you. When you change both struct members to pointers, you do get following compiler warnings:
str.c:11:5: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char **’ [-Wformat=]
printf("NAME: %s", test.name);
^
str.c:12:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("\nAGE: %d", test.age);
What does those mean? So effectively you have changed it to 2D character array and a integer array (or int*). It still works because the starting address of them both remains the same still. So accessing a variable or a pointer just with starting address yields the same result. However, you do notice difference if you did something like,
test.age++
In case of age being an int, that increments the value by 1. In case age being an int* in increments the pointer to the next slot (sizeof(int) increment).
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 7 years ago.
Improve this question
I don't understand why the following code doesn't work:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>
struct data
{
int age;
char name[20];
};
int main()
{
struct data element[2];
for (int j = 0; j < 2; j++)
{
element[j] = (struct data) malloc(sizeof(struct data));
printf("Enter fav number%d? \n", j);
scanf("d", &element[j].age);
printf("Enter fav word? \n");
scanf("s", &element[j].name);
}
printf("\nThis is what you entered:\n");
for (int k = 0; k < 2; k++)
{
printf("%d. Fav number: %d\n", k, &element[k].age);
printf("%d. Fav word: %s\n", k, &element[k].name);
}
return 0;
}
The compiler error says:
beispiele.c: In function ‘main’:
beispiele.c:199:51: error: conversion to non-scalar type requested
element[j] = (struct data) malloc(sizeof(struct data));
^
beispiele.c:201:3: error: too many arguments for format [-Werror=format-extra-args]
scanf("d", &element[j].age);
^
beispiele.c:203:3: error: too many arguments for format [-Werror=format-extra-args]
scanf("s", &element[j].name);
^
beispiele.c:208:3: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Werror=format=]
printf("%d. Fav number: %d\n", k, &element[k].age);
^
beispiele.c:209:3: error: format ‘%s’ expects argument of type ‘char *’, but argument 3 has type ‘char (*)[20]’ [-Werror=format=]
printf("%d. Fav word: %s\n", k, &element[k].name);
^
cc1: all warnings being treated as errors
element[j] is not a pointer and is a member of the array so already it has memory allocated statically.
If you need to allocate memory then have array of pointers.
struct data *element[2];
There is no need for using malloc (the array allocates all the memory).
Note, using printf does not require the address of the variable, so the & must be omitted before the variable. You do with scanf, as you must pass the address of the variable to which you want to write so that it can be modified (note the %d and %s in the scanf too). However, with the char[20], you do not need the & as the array is a pointer to the begin of the sequence of 20 characters.
int main()
{
struct data element[2];
for (int j = 0; j < 2; j++)
{
printf("Enter fav number%d? \n", j);
scanf("%d", &element[j].age);
printf("Enter fav word? \n");
scanf("%s", element[j].name);
}
printf("\nThis is what you entered:\n");
for (int k = 0; k < 2; k++)
{
printf("%d. Fav number: %d\n", k, element[k].age);
printf("%d. Fav word: %s\n", k, element[k].name);
}
return 0;
}
You have several problems:
Format specifiers start with a % sign. So change
scanf("d", &element[j].age);
to
scanf("%d", &element[j].age);
and
scanf("s", &element[j].name);
to
scanf("%s", element[j].name);
Wondering why I removed the & from the above scanf? It is because array names gets converted to a pointer to its first element.
These
printf("%d. Fav number: %d\n", k, &element[k].age);
printf("%d. Fav word: %s\n", k, &element[k].name);
should be
printf("%d. Fav number: %d\n", k, element[k].age);
printf("%d. Fav word: %s\n", k, element[k].name);
because the %d in the printf expects the value(int) and not the address of the variable(int*). Similarly, %s expects a char*, not a char(*)[20]
The cast here is completely wrong and should be removed:
element[j] = (struct data) malloc(sizeof(struct data));
This is done because malloc returns void* which can be assigned to any pointer type without casting.
etc See other answers.
You're getting 3 types of errors:
beispiele.c:199:51: error: conversion to non-scalar type requested
element[j] = (struct data) malloc(sizeof(struct data));
Check the documentation for malloc - it returns a void pointer to the allocated memory, which you then try to cast to a struct. The struct is obviously not a pointer type, hence the error message.
To be precise, the error message tells you that you're trying to cast to a type that is not scalar (roughly and incorrectly speaking, that is not a "basic" language type). C-style cast is very permissive and would happily perform many casts, for example, a long long * to a long long, without even a warning.
Keep in mind that you should not cast the pointer you get from malloc.
Also, as others have pointed out, this statement:
struct data element[2];
declares and automatically allocates the element variable. By calling malloc, you're asking the compiler to allocate it again, dynamically. If you're confused about memory allocation, take a look here.
beispiele.c:201:3: error: too many arguments for format [-Werror=format-extra-args]
scanf("d", &element[j].age);
Format strings used by scanf and printf use format specifiers starting with the % symbol, which is missing in all your calls. In this specific call, your format string "d" contains 0 format specifiers, so scanf expects 0 variable addresses to store values in. But you provide 1 address, so the compiler complains for "too many arguments".
Also, note that scanf needs a the address of a variable because arguments are passed by value - if it took the variable itself instead, it couldn't store the data to be accessible after the scanf call returned. By contrast, printf does not need to modify variables, so it takes variables rather than their addresses.
^ beispiele.c:208:3: error: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Werror=format=]
printf("%d. Fav number: %d\n", k, &element[k].age);
This error message is pretty self-explanatory. Refer to the previous point about printf's arguments.
malloc returns a pointer to the allocated data, not the actual data. You should not cast the result of malloc.
Fix the code accordingly:
struct data* element[2];
...
element[j] = malloc(sizeof(struct data));
...
free(element[j]);
malloc returns a pointer to allocated memory, but you cast the pointer to a struct data. This is what the compiler complains about
error: conversion to non-scalar type requested
Furthermore, you don't need to allocate memory at all, because you already did so by
struct data element[2];
So, when you drop the malloc line, this error should be gone.