I'm trying to write a C program for mad libs game:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char color[20];
char Noun[20];
char celebrity[20];
printf("Enter the color");
scanf("%s", color);
printf("enter the Noun");
scanf("%s", Noun);
printf("enter the celebrity");
scanf("%s", celebrity);
printf('roses are %s\n', color);
printf('%s are blue\n', Noun);
printf('I love %s\n', celebrity);
return 0;
}
After I type in my input at the "shell> " prompt, gcc gives me the following error:
Segmentation fault (core dumped)
Why do I get this error?
You don't limit the size of the scanned data (so it can write out of bounds if the input is larger than the len 20 arrays)
None of your arrays are initialized, so
Since you don't verify the return value from scanf, if a scanf fails, you'll try to read from uninitialized arrays
The last three of your format strings for your printf calls are using ' as the delimiter, not ", so they're actually character literals (yes, it's weird that C allows this syntactically), and their numeric value is being interpreted as a pointer that likely points to pure garbage; replace the single quotes with double quotes (").
#4 would almost certainly cause a segfault if the code got that far, but #1 could conceivably cause a segfault before you got to that point (and #2 and #3 could combine to cause a segfault if #4 was fixed).
Related
As described in the heading, the terminal delivers the error: zsh: segmentation fault. Here is the - pretty basic - code:
#include<stdio.h>
int main(){
int age = 0;
printf("Input your age!");
scanf("%d", &age);
printf(age);
}
thanks for the help solving this problem :)
printf(age);
should be printf("%d", age);
You need to pass in a string literal (eg: "hello world") with a format specifier (exactly the same way you did it in scanf) and then pass the age (not its address as you did with scanf, so without the &) as a second argument.
for example
printf("I am %d years old\n", age);
For the above example, I printed a message that writes "I am [age] years old" and then continues down to a new line (that's the '\n'). The '%d' is a format specifier; what it does is it specifies that in its position, the function should print a value of a specific type (%d specifies an integer). You can have multiple of these specifiers and it prints the arguments you give it in linear order. I would highly recommend you look at this[1], it should explain it better than I can.
I am using Ubuntu 14.04 and gcc 4.8.4
#include<stdio.h>
void main()
{
char c[15];
printf("enter a character\n");
scanf("%15c",c);
printf("%s\n",c);
}
Output:
enter a character
qwertyuiopasdfghjkl
qwertyuiopasdfg
When I execute the program above with more than 15 characters as input, the output does not return garbage values. But when I execute the program below:
#include<stdio.h>
void main()
{
char c[5];
printf("enter a character\n");
scanf("%5c",c);
printf("%s\n",c);
}
I am giving input which is more than 5 characters. It returns output with garbage values.
The %c directive is for reading individual characters and character arrays, but not for those arrays specifically used as C strings. In particular, it does not store a null character after the last character transferred from the input.
Therefore, both of your scanf() calls are perfectly fine, but the subsequent printf() calls are not. In each case, the contents of the array designated by c are not null-terminated, therefore attempting to print the array via an %s directive will cause scanf() to read past the end of the array, producing undefined behavior. That the undefined behavior in one case seems reasonable to you and the undefined behavior in the other case does not is irrelevant.
I advise against working with unterminated string-like arrays as you are doing. It would be better to make the arrays large enough for a terminator, and to ensure that they are, in fact, terminated. But if you must print unterminated or possibly unterminated character arrays via printf(), then be sure to use the precision field of the directive to limit the number of characters that may be printed:
#include<stdio.h>
int main(void) {
char c[5];
printf("enter a character\n");
scanf("%5c", c);
printf("%.5s\n", c);
}
You are using the wrong format specifier in scanf for a string.
#include <stdio.h>
int main(void) {
char c[15];
printf("enter a string\n");
scanf("%14s", c); // change %c to %s
printf("%s\n", c);
return 0;
}
Note that the length limit is one less than the array size, to allow room for a nul terminator.
If your input is more than 5 characters then your program will displays 5 characters perfectly and then start displaying garbage value because while printing the string it will print upto '\0' character. And if '\0' is not present at last then it will print garbage.
I'm running a while loop so the user can constantly enter expressions, until they indicate they want to quit the program. I'm using strcmp() to compare two strings so as soon as they enter quit the program will stop. But the program keeps going, any Ideas?
#include <stdio.h>
#include <string.h>
int main()
{
int min12=0;
char opper;
int x=0;
int min13;
char *Repeatprog="cont";
char *Repeatprog1="quit";
while (strcmp(Repeatprog,Repeatprog1))
{
printf("enter the integer number \n");
scanf( "%d %c %d", &min12, &opper, &min13);
printf("%d %c %d\n", min12, opper, min13);
printf("Type the word quit to end program\n");
scanf("%s", Repeatprog);
}
printf("Good Bye");
return 0;
}
Remember always that an Array is a Pointer to the first object of the array.
And secondly, in your call to scanf() you only read a character. Not a whole string (represented by %s in C)
So in conclusion, your call to scanf() shouldn't have a pointer and should have a string instead of a character.
scanf("%s", Repeatprog);
or simply
gets (Repeatprog);
EDIT :
As the commenter #EOF said, gets() is not a good idea since it can lead to Undefined Behaviour. That's because the program can read more characters than it should have and lead to overflow, thus it isn't secure.
So I recommend using char *fgets(char *str, int n, FILE *stream)
Note:
Also, your code is using string literals. So if you make any attempt to change the content of the char pointer then it will lead to Undefined Behaviour.
For this note, please thank the guys below me [comments]. I made a huge mistake and I'm sorry.
I have written this program in Linux. I assigned the character array size to 10. Upon entering up to 23 characters, the program showed no error. But on the 24th character, it showed a segmentation error. Please tell me why we can enter excess characters.
#include <stdio.h>
void main ()
{
char a[10];
scanf("%s", &a);
printf("%s", a);
}
First remove & from scanf.Like
scanf("%s", a);
char a[10] allocates the array on the stack for 10 char only. now when you enter characters as soon as you get out of bounds you are overwriting other useful things like the stack frame of the scanf call.
This out-of-bounds behavior is undefined by the C standard,
I am writing following c code and getting an error :
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *prot;
char addr[20];
FILE *fp;
int i = 0;
int tos,pld;
prot = (char *)malloc(sizeof(char *));
//addr = (char *)malloc(sizeof(char *));
printf("\n enter the protocol for test::");
scanf(" %s",prot);
printf("\n enter the addr::");
scanf(" %s",addr);
printf("\n enter the length of the payload::");
scanf(" %d",pld);
printf("\n enter the tos :: ");
scanf(" %d",tos);
I am getting the following error while entering the value.There is a segmentation fault coming could anyone tell me why this segment fault is coming:
enter the protocol for test::we
enter the addr::qw
enter the length of the payload::12
Segmentation fault
prot = (char *)malloc(sizeof(char *));
Should be:
prot = malloc(sizeof(char) * SIZE); // SIZE is the no. of chars you want
Another problem is: You should use & for integers in scanf()!
With changes:
printf("\n enter the length of the payload::");
scanf(" %d",&pld);
printf("\n enter the tos :: ");
scanf(" %d",&tos);
The segmentation fault is because scanf expects a pointer to the variable the scanned value shall be stored in, but you pass the variable pld itself. That is uninitialised and hence when interpreted as a pointer points into the wild. The same happens with the tos. And of course, you should allocate the proper amount of space for prot as has otherwise been pointed out.
Your memory allocation for prot has allocated 4 bytes (on a 32-bit system) or 8 bytes (on a 64-bit system) for the string. If you read more than that into it, you are overflowing your buffer.
Unless there was a good reason to do otherwise, I'd simply use:
char prot[128];
for any suitable size for the string.
You should also check all your scanf() calls to ensure they succeed; you should probably apply a limit to the size of the strings. For a char prot[128];, the safe conversion is %127s; the null is not counted in the conversion specification.
If your compiler was not warning you about these lines:
scanf(" %d",pld);
scanf(" %d",tos);
you either need to turn on more warnings or get a better compiler. If it was warning you, pay heed to your compiler; it knows more about C than you do (and probably more about it than I do, too).
scanf(" %d", &pld);
scanf(" %d", &tos);
This is probably not the source of your current problem, but it is a bug:
prot = (char *)malloc(sizeof(char *));
I doubt you meant to make a buffer the size of one character pointer.
Anyway, to pinpoint your immediate issue, please run your program under valgrind and/or a debugger. In this particular case just enabling compiler warnings would have caught your problem, which is that you're passing integers by value where you should be passing by pointer to scanf. This could have been solved by the compiler, instead of coming to us, if only you enable the relevant options.
scanf expects pointers to the variables you're filling (except in the case of strings, which are already pointers to char).
Try
scanf(" %d", &pld);
and the same with tos.
scanf family of functions are main source of problems in homework.
They always expect addresses, so they can be used as OUTPUT.
They cannot be type-checked because the prototype of that part is ..., so you can put anything there. compiler does not complain.
When things don't work, check the receiver arguments, they need to be address of items to be written into, and the type has to match what your specify in the format string.