c: segfault when using scanf with a character [closed] - c

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 8 months ago.
Improve this question
I am writing a simple program that takes in user input (a char) and does a simple calculation. However, it segfaults before even hitting scanf.
The other posts I've looked at (below) fix the problem by adding more memory to the char buffer, or passing the address of the variable instead of the variable itself, etc., but that doesn't fix the problem.
Why is this happening and how do I fix it?
other posts I've looked at:
Segfault when using scanf()
C Programming segfault on scanf
SegFault after scanf?
#include <stdio.h>
int main(int argc, const char * argv[]) {
char piece_type;
printf("Enter piece type (k, b, p):\n");
scanf('%c', &piece_type ); //segfaults here
/*other code */
return 0;
}

The first argument to scanf must be a pointer to a string. Most often it is given as a string literal, such as "%c", which is automatically converted to a pointer to its first element.
'%c' is not a string or a pointer to a string. It is a multicharacter constant, which is effectively an int constant.
Enable warnings in your compiler and elevate warnings to errors. With Clang, start with -Wmost -Werror. With GCC, start with -Wall -Werror. With MSVC, start with /W3 /WX.

Instead of the format string in this call of scanf
scanf('%c', &piece_type ); //segfaults here
^^^^
you are using a multibyte integer character constant that has the type int. So the call invokes undefined behavior.
You need to use a string literal
scanf("%c", &piece_type );
Also it is better to include a leading space in the format string like
scanf(" %c", &piece_type );
^^^^
This allows to skip white space characters in the input buffer.

As Eric said, you have to provide string (see reference) int scanf ( const char * format, ... );
One of the following should solve your problem:
replace '%c' with "%c" so the code should look like this
...
printf("Enter piece type (k, b, p):\n");
scanf("%c", &piece_type );
/*other code */
...
use getchar() instead (reference - int getchar ( void );)
...
printf("Enter piece type (k, b, p):\n");
piece_type = getchar();
/*other code */
...

Related

Program crashes in the `scanf` function. Why? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char** argv)
{
char key, vector;
char plainText[101];
char cipher;
int i, cipherValue;
int keyLength, IVLength;
scanf("%s", key);
scanf("%s", vector);
return 0;
}
My program crashes after I input values for the scanf parts. I don't understand why.
The problem with
scanf("%s", key);
scanf("%s", vector);
is:
key and vector are of type char, not pointers to char. The can hold one character only.1
With %s scanf expects a pointer to char. As it stands right now, you
are passing uninitialized integer values as if it were pointers, that's
undefined behaviour and your program crashes as a result of it. The compiler
must have given you a warning about this, don't ignore the compiler's warnings,
they are there to help you, not annoy you.
The correct version:
char key[101], vector[101];
...
scanf("%s", key);
scanf("%s", vector);
// or to limit the number of bytes
// written in the buffer, as pointed out
// in the comments by user viraptor
scanf("%100s", key);
scanf("%100s", vector);
For more information about scanf, please read the documentation
Footnote
1A string in C is a sequence of characters that ends with the
'\0'-terminating byte. A string with one single character needs a char array
of dimension 2 or more. In general, a char array of dimension n can store
strings with maximal length of n-1. You have to keep that in mind when passing
pointers to char to functions when they expect strings. A pointer to a single
char will lead to undefined behaviour because it overflows.

C Programming- Scanf not working. Tried adding space, doesnt work [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
int main(int argc, char *argv[]) {
int option;
char user[50];
system("COLOR b");
printf("~~~~~~~~~~~~~~~~ GLENMUIR HIGH SCHOOL LIBRARY MANAGEMENT SYSTEM ~~~~~~~~~~~~~~~~~~~~~~~ \n");
printf("Username:");
scanf("%c",&user);
checkPass();
printf("\n | Options Menu |\n");
printf(" | Check Out Book(1), Return Book(2) , Register(3), Admin Login (4) |\n");
printf("Option:");
scanf("%d",&option); /*compiler ignores this completely*/
I tried adding space before %d, but still didn't work. Any solutions for a newb?
Your problems stem from this statement:
scanf("%c",&user);
The %c conversion specifier only reads a single character from the input stream, not a string. If you entered a username like jbode, only the 'j' character is read from the input stream - the remaining characters will be read by the next scanf (or other input) call.
Unfortunately, that next scanf call is expecting a sequence of decimal digits due to the %d conversion specifier; 'b' is not a decimal digit, so you get a matching failure - option is not updated, 'b' is not removed from the input stream, and scanf returns a 0 to indicate that no successful conversion occurred.
The right answer is to not use scanf to read the username at all, but to use fgets instead:
if ( !fgets( user, sizeof user, stdin ) )
{
// EOF or error detected on input, handle as appropriate
}
checkPass();
...
If you really want to use scanf, though, the right approach would be:
if ( scanf( "%49s", user ) != 1 ) // no & operator on user
{
// EOF or error detected on input, handle as appropriate
}
checkPass();
...
You do not need to use the & operator when reading a string into an array of char. The expression user will implicitly be converted ("decay") from type char [50] to char *, and the resulting pointer value will be the address of the first element of the array.
From standard 7.21.6.2 under the conversion specifiers and their meanings:
s
Matches a sequence of non-white-space characters.286) If no l length
modifier is present, the corresponding argument shall be a pointer to
the initial element of a character array large enough to accept the
sequence and a terminating null character, which will be added
automatically.
Well as an alternative to scanf you can try looking at fgets.
So the answer will be scanf("%s",user); or more correct use would be scanf("%49s",user). To get a more elanorate idea of why you should consider fgets over scanf read through this discussion.
Also there is no need to put space before %d format specifier because as per standard 7.21.6.2
Input white-space characters (as specified by the isspace function)
are skipped, unless the specification includes a [, c, or n specifier.
Apart from the change mentioned above check the return value of scanf.
if( scanf("%49s",user) != 1){
fprintf(stderr,"You have given wrong input - use input just a word\n");
exit(1);
}
In your case if you have given wrong input then this would fail and you will get the error message.
You can use %d specifier in scanf like this, no need to provide ' '.
if( scanf("%d",&option)!= 1){
/* handle error. Put appropriate meaningful error message. */
exit(1);
}
Also in Dev-cpp try to add compiler flags -Wall -Wextra that will show you warnings.
Go to Tools -> Compiler Options
Now in general tab under Adds the following command when compiler is called and -Wall -Wextraand pressOK`,=.
Compile it. You will get some error like this - [Warning] format %c expects argument of type char *, but argument 2 has type char (*)[20] [-Wformat=]`
&user denotes an pointer to an array of chars containing 20 char. But as mentioned above you have to pass char* as second argument to scanf.

please tell me why does the output of the two picture is different? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
This program accept 5 string and print them.
here is the program:-
#include"stdio.h"
#include"conio.h"
void main(){
clrscr();
char s[5];
for(int i=0;i<5;i++){
scanf("%s", s[i]);
}
for(i=0;i<5;i++){
printf("\n\n%s", s[i]);
}
getch();
}
when i execute this program the output will be this
Click here to see the output of the program
but when i enter the string in different way it print wrong output
Click here to see the output of the program
You are reading a string into a char, or rather, the string you read starts at the char position i in s. As s is very short (and when i is 5 it is empty), there will be an overflow, causing undefined behavior.
You want to have an array of strings, not of chars, as Blue Pixy mentions in his comment, e.g. char s[5][32];.
Also turn warnings on. The i in the second for loop is not defined.
You've declared s as a 5-element array of char; each s[i] can store a single character value, not a string. Since you don't explicitly initialize each s[i], they contain an indeterminate value.
The argument corresponding to the %s specifier in scanf must have type char * (each s[i] has type char), and it must point to the first element of an array of char large enough to store the string contents (including the 0 terminator that marks the end of the string).
When you call
scanf( "%s", s[i] );
you're telling scanf to store the next sequence of non-whitespace characters to the address corresponding to the value stored in s[i], which is a) indeterminate and b) likely not valid. The resulting behavior is undefined, meaning pretty much anything can happen - your code may work as expected, it may crash outright, it may give you garbled output, it may corrupt other data, etc.
As written, s can store a string up to 4 characters long.
If you want to store an array of strings, then s needs to be a 2-dimensional array of char:
#define MAX_STRING_LENGTH 20 // or however long you expect your longest string to be
...
char s[5][MAX_STRING_LENGTH + 1];
Each s[i] can now store a string up to MAX_STRING_LENGTH characters. The rest of your code should now behave as expected.

invalid conversion from `char' to `char*' [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 8 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Improve this question
code is :
int main() {
int i,last;
char TXT[500];
printf("Donnez un exemple ?\n");
gets(TXT);
last = strlen(TXT);
for(i=0;i<50;i++){
if (i==0){
strcpy(TXT[1],TXT[0]);
} else {
strcpy(TXT[i-1],TXT[i]);
}
}
getch();
return 0;
}
error in line : strcpy(TXT[1],TXT[0]);
What is the cause of the problem ?
The strcpy function takes two char* (technically, a char* and a const char*). Moreover, it is not allowed to pass strcpy overlapping buffers.
It looks like you wanted to write
TXT[i-1] = TXT[i];
(this would delete the leading character from the string).
for(i=1 /* one, not zero */ ; i<50 ; i++) {
TXT[i-1] = TXT[i];
}
Good, but I want to use strcpy. How?
You are not allowed to use strcpy without an intermediate buffer. If you must use strcpy, do it like this:
char TXT[500], TMP[500];
printf("Donnez un exemple ?\n");
fgets(TXT, 499, stdin);
strcpy(TMP, &TXT[1]); // Note that 'for' loop is no longer required
TXT is an array of 500 characters.
So, TXT[1] and TXT[0] are individual characters (just one single letter).
TXT[0] is the very first character in the array.
TXT[1] is the second character in the array.
The function strcpy expects you to pass POINTER-to-characters (type char*) for both parameters.
And instead, you're passing a single character.
Can you explain what the purpose of this program is?
Maybe we can help you fix it then.
TXT[i] is of type char. But strcpy expects parameters of type char* since it operates on null-terminated strings. Hence the compilation error.
As for how to fix it, that depends on what your code is trying to do. Perhaps all you meant to do was
TXT[1] = TXT[0];
STRING FUNCTIONS WORKS ON STRING NOT ON CHARACTERS
ARE YOU TRYING TO SWAP THE WORDS OR CHARACTERS ?

I am trying to do a program that picks a vowel from the user input [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
char *v= "a";
char *o='e';
char * w='i';
char *e='o';
char *l='u';
char *u[1];
printf ("please enter your character\n");
scanf ("%c",& u);
if (u == v){
puts("the character is it a vowel\n");
}
if (u == o) {
puts("the character is it a vowel\n");
}
else
puts("the character is a constant\n");
system("PAUSE");
return 0;
}
i need help in getting the right answer in finding a vowel from the user input.
First of all, shame on you for ignoring all of the compiler warnings you certainly received. They are there to help prevent you from doing "stupid things."
And why all this nonsense? This is the first of the "stupid things" the compiler is trying to tell you about.
char *v= "a";
char *o='e'; // invalid - Initializing a pointer to a constant 'e' (101).
char * w='i'; // invalid
char *e='o'; // invalid
char *l='u'; // invalid
Are you familiar with how pointers work? If not, I suggest you do some reading and understand them.
The first line makes sense - you're making a string and pointing char* v to that string.
But there's really no point in using pointer for those characters - or even variables at all. Just compare them directly:
char my_character;
if (my_character == 'a') {
// do something
}
And as for reading the character, again, you're using pointers when it doesn't make sense:
char *u[1]; // why?
Instead, just define a single char variable. Now, go look at the documentation for scanf. Giving it a format string of "%c" means, "I want to read just one character". Then, you need to tell where scanf to put it. You do this by passing it the "address of" the variable you want to store it in. You do this with (unsurprisingly!) the address of operator &.
char input_character;
scanf("%c", &input_character);
Armed with this information, you should be able to complete your work. Next, I suggest you look into the switch statement.
Finally, you must use consistent formatting (indentation, spacing) and use meaningful variable names, if you have any desire of ever being taken seriously as a programmer. Spelling out "vowel" for your pointless variables may be "cute" but it's total nonsense.
Most importantly, you should never write a single line of code, unless you understand exactly what it does. If you do this, then do not go asking anyone for help (especially not StackOverflow). If you can't explain what your code is doing (or at least what you think it's supposed to do), then you don't deserve for your program to work.

Resources