I don't know why this program doesn't work:
char syze;
printf("Please enter your desired size (Choose from S,M,L,XL)\n");
scanf("%s", &syze);
if(syze =='S')
{printf("Available");}
else if(syze =='M')
{printf("Available");}
else if(syze =='L')
{printf("Available");}
else if(strcmp(syze,"XL")==0)
{printf("Available");}
else
{printf("Please enter a valid character");}
return 0;
The problem is in
scanf("%s", &syze);
in your code, size is of type char and you should be using %c format specifier to scan the input.
If you use %s format specifier to scan the input for a char, essentially you'll be overrunning the allocated memory thereby creating undefined behaviour
Then,
strcmp(syze,"XL")
is also wrong, as strcmp() needs a (const)char * as both the arguments, and you're passing a char as the first one. You can simply make use of the equality operator, == to compare a char.
Finally, a char will never be able to hold "XL".
Solution: If you need to have "XL" as one of the inputs, you may want to change syze to an array, like
char syze[3] = {0};
or likewise. In that case, you can keep the scanf() as
scanf("%2s", syze);
and compare your inputs using strcmp().
You have a problem in strcmp(syze,"XL")==0. You can't compare a char to a string XL. Use only X for that choice and compare the same as the others if(syze =='X').
You have another problem in scanf("%s", &syze);. Use %c to scan a char:
scanf("%c", &syze);`
If you want to keep using the choice "XL", you should declare syze as char syze[3] and compare all choices using strcmp.
Related
#include <stdio.h>
#include <stdlib.h>
int main() {
char a;
printf("What? \t");
scanf("%s", &a);
printf("U have to %s", a);
return 0;
}
Whenever I build and run this code and enter a value in %s, I get an error and the debug program stops working and closes. But when I use ampersand sign like this:
#include <stdio.h>
#include <stdlib.h>
int main() {
char a;
printf("What? \t");
scanf("%s", &a);
printf("U have to %s", &a);
return 0;
}
in the printf... it works. Why is that? It also differs between the format specifier, such as one doesn't need to put & (ampersand) sign in printf when one uses %c or %d in the scanf. Why does this happen and is it related to the data types and which format specifiers concludes this result?
(sorry for my bad English. I am not a native English speaker and this is my first time here).
What you have here is a classic example of code that seems to work, but for the wrong reasons.
Let's review a few things about printf and scanf. The format specifier %d is for values of type int. You can read an integer like this:
int i;
scanf("%d", &i);
And you can print it back out like this:
printf("%d\n", i);
Why does one use an & and one does not? Well, C uses what's called "pass by value". If we wrote
scanf("%d", i); /* WRONG */
we would be passing the value of i to scanf. But we don't want to pass the (old) value of i to scanf, we want scanf to read a new value, and store it into i. In other words, we want scanf to, in effect, pass the new value of i back to us. For that to work, we instead pass scanf a pointer to the variable i where we want it to store the just-read integer. That's what the & does -- it generates a pointer to i.
When we call printf, on the other hand, the regular way of passing arguments works just fine. We do want to pass i's value to printf so that it can print it out. If we were to call
printf("%d\n", &i); /* WRONG */
it wouldn't work, because printf expects an int, and here we're wrongly handing it a pointer-to-int.
So now we've learned that for integers with %d, printf wants an int and scanf wants a pointer-to-int.
Let's talk about characters. The format %c is for characters. We can read one character with scanf:
char c;
scanf("%c", &c);
And we can print it with printf:
printf("%c\n", c);
Again, the pattern is exactly the same. scanf needs a pointer, so that it can fill in the value, so we pass &c. But printf just needs the value, so we pass plain c.
Now we get to strings. A string in C is an array of characters. Also strings in C are always terminated by a special null character, '\0', that marks the end of the string. So if we wanted to declare a variable that could contain strings up to 9 characters long, we might write
char s[10];
That gives us room for 9 characters, plus the terminating '\0'.
But arrays are special in C: Whenever you pass an array to a function, or whenever you do anything that would require the "value" of the array, what you get instead (what the compiler automatically generates for you) is a pointer to the array's first element.
What this means is that to read a string with scanf and %s, we can just call:
scanf("%s", s);
"But where is the &?", you ask. "I thought you always needed an & when calling scanf!"
Well, not quite. You always need a pointer when calling scanf. And in fact, when you called scanf("%s", s), it was just as if you had written
scanf("%s", &s[0]);
When you use %s with scanf, it expects a pointer to the first of several characters, that is, a pointer to the beginning of an array of characters, where it should begin writing the string it reads. (How does it know how big the array is? What if the user types a string that's too long to fit in the array? We'll get to those points in a moment.)
You can print strings with %s too, of course, and it looks like this:
printf("%s\n", s);
This is, again, just as if you had written
printf("%s\n", &s[0]);
When you use %s with printf, it expects a pointer to the first of several characters which it should begin printing, until it finds the terminating '\0' character.
So %s is special with printf and scanf, because strings are special (because arrays are special). With %d and %c and just about every other format specifier, you usually need a & when you call scanf, and you usually don't want that & when you call printf. But with %s, you usually don't want the & for either printf or scanf.
(And if we think about it a bit more carefully, the exception is not so much that scanf and %s does not need the &. Remember, the rule is really, scanf always needs pointers. The only reason scanf and %s doesn't need an & is that when you pass an array, you get a pointer to the array's first element automatically. So the exception is really for printf and %s: printf and %s does expect a pointer, and the reason printf and %s is designed to expect a pointer is that there's no way to not give it one: it has to accept a pointer, because for strings, that's what you always end up giving it.)
So the rule with %s is that scanf expects a pointer to the first of several characters, and printf expects a pointer to the first of several characters, too.
So now, with all that background out of the way, we can look at your code. You basically wrote
char c;
scanf("%s", &c);
At first this might seem to be kinda, sorta, almost correct. scanf and %s wants a pointer to a character, and you gave it &c, which is a pointer to a character. But %s really wants a pointer to the first of several characters. But you gave it a pointer to just a single character. So when the user types a string, the first character typed will get stored in c, but the rest of the characters, and the terminating '\0', will get written to unallocated memory somewhere off to the right of variable c. They'll overwrite ("clobber") memory that was, perhaps, used for something else. This is a serious problem, but it might not become evident right away.
Finally, you tried to print things out again with printf. You first tried
printf("%s\n", c); /* WRONG */
but this didn't work at all. The reason is that %s with printf expects a pointer-to-char, but you gave it a plain char. Suppose c contains the letter 'A'. This would end up asking printf to go to address 65 and begin printing characters until it finds the terminating '\0'. Why address 65? Because 65 is the ASCII code for A. But there's probably not a proper, null-terminated string starting at address 65 in memory; in fact there's a good chance your program doesn't have permission to read from address 65 at all.
So then you tried
printf("%s\n", &c); /* ALSO WRONG */
and this seemed to work. It "worked" because, if scanf succeeded in storing a complete string into c and the unallocated memory off to the right of it, and if clobbering that memory somehow didn't cause (too many) other problems, then when you pass the pointer &c to printf, printf can find those characters, making up a string, and print them out.
So it "works", but as I said, for the wrong reasons: in the process it stomps all over memory it doesn't "own", and sooner or later, something else is going to not work as a result.
How should you have scanned and printed a string? One way is like this, as we saw before:
char s[10];
scanf("%s", s);
printf("%s\n", s);
Now when scanf gets a pointer to the first element of the array s, it has 10 characters to play with.
We really do have to worry about the possibility that the user will type more than 9 characters. But there's a fix for that: we can tell scanf how long a string it's allowed to read, how many characters it's allowed to write to the array we handed it:
scanf("%9s", s);
That 9 in there tells scanf that it's not allowed to read more than 9 characters from the user. And since 9 is less than 10, there's still room for the terminating '\0' character.
There's much more that could be said about scanf. As chqrlie noted in a comment, it's important to check its return value, to make sure it succeeded in converting as many values as you wanted it to. It's got some strange rules about whitespace. Unless you know what you're doing, you can't intermix calls to scanf with calls to other input-reading functions like getchar or fgets -- you'll get strange results. And, finally, scanf is so persnickety and (in the end) so lacking in truly useful functionality that it's not really worth using at all. But those are topics for another day, since this answer is tl;dr already.
The %s format specifier requires a pointer to a string. When used with scanf, it must be a char array with enough characters for the word you enter plus the trailing null byte that indicates the end of the string. In printf() it has to be a null-terminated char array.
Using a pointer to a char variable doesn't work, because it doesn't have room for the null byte. You're causing undefined behavior by writing outside the variable.
char word[100];
scanf("%s", word);
printf("%s\n", word);
You can use %c to read and write a single character rather than a string of multiple characters.
char letter;
scanf("%c", &letter);
printf("%c\n", letter);
In statement char a; a is a character variable & to scan a char variable use %c format specifier.
scanf("%s",a);/* %s expects base address of char buffer, not single char */
scanf(" %c",&a);/* this is correct */
If you want to scan using %s then your input should be char buffer like char buf[10]. for e.g
char a[10];
scanf("%s",a);
u don't need to put &(ampersand) sign in printf when u use %c or %d ? no need to provide address & to printf() as printf() job is to print not to scan. for e.g
char input;
scanf("%c",&input);/* here you need &, As scanf() will store input char into
address you provided i.e &input */
printf("%c",input);/*here no need &input, bcz input char already stored,
printf will just print the char*/
Well, if you print the address you can use %p.
printf("%p",a);/*a is char buffer */
I have a fairly basic problem but I can't manage to solve it.
I'm trying to get an input from a user like this :
int main() {
char coord[2];
fflush(stdin);
scanf("%c", coord);
}
When i'm trying this code with printf("%c", coord);, it displays a completely different string from what I typed. For example, if I type "g6", it prints "Ê". I really have no clue why it's happening.
Thanks for helping me !
If you want to get string(char array) from user you should do this :
scanf("%s",coord);
%c is for single char
First of all avoid using fflush (stdin);. Standard input flashing is undefined behavior, according to C standard, and may lead to big issues .
Then, you are trying to get an input string using %c format, that is supposed to acquire a single character. Furthermore, your coord array has not enough room for the string terminator character (\0).
The format to be used in order to acquire a string with scanf (and to print it with printf) is %s:
int main() {
char coord[3] = {0};
scanf("%2s", coord);
printf ("%s\n", coord);
}
The "2" added to the format makes sure that at most two characters are read (exactly those you can have in you string array without overwriting the last character).
For starters this statement
fflush(stdin);
has undefined behavior and shall be removed.
The conversion specifier %c of printf expects an argument of the type char while you are passing an expression of the type char * to which the array designator is implicitly converted
printf("%c", coord);
you have to write either
printf("%c", *coord);
or
printf("%c", coord[0]);
Pay attention to that using this call of scanf
scanf("%c", coord);
you can enter only a single character. You can not enter a string.
If you want to enter a string in the array coord that has only two elements then you have to write
scanf( "%1s", coord);
In this case the array will be filled with a string of length equal to 1.
In this case you can output it like
printf("%s", coord);
If you want to enter a string like this "g6" then you have to declare the array like
char coord[3];
and write the following call of scanf
scanf( "%2s", coord);
The line char coord[2]; declares coord as an array of characters (also known as a "string"). However, the %c (in both scanf and printf) reads/writes a single character.
For strings, you need to use the %s format.
Also, if you want to store/read/print the string, "g6", you will need to allocate (at least) three characters to your coord array, as you must terminate all C-strings with a nul character.
Furthermore, calling fflush on the stdin stream is not effective (actually, it causes undefined behaviour, so anything could happen) - see here: I am not able to flush stdin.
So, a 'quick fix' for your code would be something like this:
#include <stdio.h>
int main()
{
char coord[3]; // Allow space for nul-terminator
// fflush(stdin); // don't do it
scanf("%2s", coord); // The "2" limits input to 2 characters
printf("%s\n", coord);
return 0; // ALways good practice to return zero (success) from main
}
char name[2];
scanf("%c",name);
printf("%c",name);
I am just starting to learn C. I'm curious about the above code, what I got from the printf output, is not the same with the character I typed in. Rather the output was some funny looking symbol. Can someone explain this to me?
For the %c specifier, scanf needs the address of the location into which the character is to be stored, but printf needs the value of the character, not its address. In C, an array decays into a pointer to the first element of the array when referenced. So, the scanf is being passed the address of the first element of the name array, which is where the character will be stored; however, the printf is also being passed the address, which is wrong. The printf should be like this:
printf("%c", name[0]);
Note that the scanf argument is technically ok, it is a little weird to be passing an array, when a pointer to a single character would suffice. It would be better to declare a single character and pass its address explicitly:
char c;
scanf("%c", &c);
printf("%c", c);
On the other hand, if you were trying to read a string instead of a single character, then you should be using %s instead of %c.
Either Read a single char
char name[2];
scanf("%c",name);
printf("%c",name[0]);
Or read a string
char name[2];
scanf("%1s",name);
printf("%s",name);
You need %s since because name contains 2 elements. %c is used for single character so if you want the user to input something for e.g. "as"(without "") and the program to print it out you need %s.
char name[2];
scanf(" %s", name);
printf("%s",name);
if you give your input which contains characters less than or equal to two you will get a correct output just as your input if your input contains characters greater than 3 then it doesn't work
int main()
{
//Define Variables
char studentName;
//Print instructions to fill the data in the screen
printf("Please type in the Students name:\n");
scanf("%s", &studentName);
printf("\n\n%s", &studentName);
return 0;
}
Seeing the above code, I am only printing to screen out the first word when I type in a sentence.
I know it is a basic thing, but I am just starting with plain C.
Read scanf(3) documentation. For %s is says
s Matches a sequence of non-white-space characters; the next
pointer must be a pointer to character array that is long
enough to hold the input sequence and the terminating null
byte ('\0'), which is added automatically. The input string
stops at white space or at the maximum field width, whichever
occurs first.
So your code is wrong, because it should have an array for studentName i.e.
char studentName[32];
scanf("%s", studentName);
which is still dangerous because of possible buffer overflow (e.g. if you type a name of 32 or more letters). Using %32s instead of %s might be safer.
Take also the habit of compiling with all warnings enabled and with debugging information (i.e. if using GCC with gcc -Wall -g). Some compilers might have warned you. Learn to use your debugger (such as gdb).
Also, take the habit of ending -not starting- your printf format string with \n (or else call fflush, see fflush(3)).
Learn about undefined behavior. Your program had some! And it misses a #include <stdio.h> directive (as the first non-comment significant line).
BTW, reading existing free software code in C will also teach you many things.
There are three problems with your code:
You are writing a string into a block of memory allocated for a single character; this is undefined behavior
You are printing a string from a block of memory allocated for a single character - also an undefined behavior
You are using scanf to read a string with spaces; %s stops at the first space or end-of-line character.
One way to fix this would be using fgets, like this:
char studentName[100];
//Print instructions to fill the data in the screen
printf("Please type in the Students name:\n");
fgets(studentName, 100, stdin);
printf("\n\n%s", &studentName);
return 0;
Try scanf("%[^\n]", &studentName); instead of scanf("%s", &studentName);
This is happening because %s stops reading the input as soon as a white space is encountered.
To avoid this what you can do is declare an array of the length required for your string.
Then use this command to input the string:-
scanf("%[^\n]s",arr);
This way scanf will continue to read characters unless a '\n' is encountered, in other words you press the enter key on your keyboard. This gives a new line signal and the input stops.
int main()
{
//Define Variables
char studentName[50];
//Print instructions to fill the data in the screen
printf("Please type in the Students name:\n");
scanf("%[^\n]s", &studentName);
printf("\n\n%s", &studentName);
return 0;
}
Alternatively you can also use the gets() and puts() method. This will really ease your work if you are writing a code for a very basic problem.
[EDIT] : As dasblinkenlight has pointed out...I will also not recommend you to use the gets function since it has been deprecated.
int main()
{
//Define Variables
char studentName[50];
//Print instructions to fill the data in the screen
printf("Please type in the Students name:\n");
gets(studentName); printf("\n\n");
puts(studentName);
return 0;
}
make the changes below and try it. I added [80] after the studentName definition, to tell the compiler that studentName is an array of 80 characters (otherwise the compiler would treat it as only one char). Also, the & symbol before studentName is not necessary, because the name of the array implicitly implies a pointer.
int main()
{
//Define Variables
char studentName[80];
//Print instructions to fill the data in the screen
printf("Please type in the Students name:\n");
scanf("%s", studentName);
printf("\n\n%s", studentName);
return 0;
}
Your problem is here
char studentName;
It is a char, not a string.
Try:
Define it as an array of chars like char studenName[SIZE];.
allocating memory dynamically using malloc:
.
char buffer[MAX_SIZE];
scanf("%s", &buffer);
char * studentName = malloc (sizeof(buffer) + 1);
strcpy (studentName , buffer);
I intend to modify each other letter of a particular string. But for the purposes of this program none of that occurs. So far I've grabbed a string from the user and stored it in userinput and intend to print it.
#include <stdio.h>
#include <string.h>
int main(void) {
char userinput[256] ="";
printf("Enter somthing to change:\n");
scanf("%s", &userinput);
printf("%s\n", userinput);
int k = 2; // This is just here to do something every time k is even
int j = strlen(userinput);
for (int i = 0; i < j; i++) {
if(k % 2 == 0) {
printf("%s", userinput[i]);
k++;
}
else {
printf("%s", userinput[i]);
k++;
}
}
}
The strlen() function however does not work on the userinput. I figure this is because strlen() is supposed to take the address of the first char of a string and then iterate until reaching a null char but scanf doesn't actually create a null char.
I couldn't figure out a way of adding the '\0' after the string without first knowing the length of the string.
How would I go about accessing the length of a stored character sequence if it's stored in an array?
This:
scanf("%s", &userinput);
should be:
scanf("%s", userinput);
The address of operator & is unrequired, and incorrect. Arrays decay to the address of their first element when passed to a function. scanf("%s") will append a null terminating character so it is unnecessary to explicitly insert one.
To prevent potential buffer overrun specify the maximum number of characters that scanf() should write to userinput. This should be one less than the size of userinput, leaving room for the terminating null character:
scanf("%255s", userinput);
The incorrect format specifier (which is undefined behaviour) is being used to print the characters of userinput: use %c not %s. This:
printf("%s", userinput[i]);
must be:
printf("%c", userinput[i]);
Change
scanf("%s", &userinput);
to
scanf("%s", userinput);
The & operator is not required in the case of String capture. The scanf() automatically appends the null character('\0') to the end of the string so int j = strlen(userinput); should work.
If you still want to calculate the length without this function efficiently here is the link How to calculate the length of a string in C efficiently?
Change this
scanf("%s", &userinput);
with
scanf("%s", userinput);
we have to use addresses for scanf:
If we will scan into an int a then we have to call scanf() with the address of a => &a
If we will scan into a double a then we have to call scanf() with the address of a => &a
But If we will scan data into with pointer (memory address) int *a; or char array char a[50]; then we have to call scanf() with the pointer or with the array without adding &
From the scanf() page
Depending on the format string, the function may expect a sequence of
additional arguments, each containing a pointer to allocated storage
where the interpretation of the extracted characters is stored with
the appropriate type. There should be at least as many of these
arguments as the number of values stored by the format specifiers.
Additional arguments are ignored by the function. These arguments are
expected to be pointers: to store the result of a scanf operation on a
regular variable, its name should be preceded by the reference
operator (&) (see example).
You're confused about types, as others have indicated. Using scanf and printf when you're confused about types is dangerous!
scanf("%s", &userinput);
The type of &userinput is char (*)[256], but scanf expects %s to correspond to a char *. Since the type expected and the type given differ and aren't required to have the same representation, the behaviour is undefined.
I figure this is because strlen is supposed to take the address of the
first char of a string and then iterate until reaching a null char but
scanf doesn't actually create a null char.
Wrong. scanf certainly does assign a null character, when you use the %s format specifier. That is, providing scanf doesn't encounter an error or EOF. On that note, you should probably check for errors from scanf:
if (scanf("%s", userinput) != 1) {
/* Insert error handling here */
}
... as you should with all standard library functions in C.
k is pointless. Your loop already increments i at the same frequency as k.
strlen returns a size_t. Make sure you store return values in the right types. If a function returns size_t, then you store the return value in size_t. If a function returns int, then you store the return value in an int. Got it? Whatever the return type is, is whatever type you use to store the return type. Use the manual to find that out.
printf("%s", userinput[i]);
There's that type confusion again. userinput[i] is a char. %s tells printf to expect a char *. When the argument is invalid, the behaviour is undefined. That may cause your program to malfunction. Consider printf("%c", userinput[i]); or printf("%s", &userinput[i]);.