C - strcmp won't work with scanf() - c

I am trying to use scanf() with strcmp. However, it doesn't work. I've included the right header files. I've tried out gets(). It works but I don't want to be vulnerable of a buffer overflow attack.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main() {
char a[100] = "Hello World!";
char b[100];
scanf("%s", &b);
if(strcmp(a, b) == 0) {
printf("This should work!\n");
}
}
I compile the program. Then, type Hello World! into the program. It won't show the message. Also, why does strcmp() show me all kinds of return values?
Please help.

Reading the manual on scanf -- you will see that it stops scanning a %s at the first whitespace found
scanf("%s", b);
of
Hello World
will give you Hello but not Wolrd
Also note that scanf is equally vulnerable to buffer overflow, as you are still not limiting the size of the input in %s -- to limit the input you should probably try to do %99s making sure that you are not reading more than your 100 byte buffer still leavng space for your null termination.
As per this question you need something like
scanf("%[^\n]",str)
to read everything up to the newline, and combining that with a length restrction, you would need something like
scanf("%99[^\n]",str)

Related

why strcmp function is not giving correct comparison result in c program

So below is my source code in c in which i have used strcmp function to compare two strings
#include<stdio.h>
#include<string.h>
int main() {
unsigned char pass[100]="Try to hack me";
unsigned char input[100];
printf("Enter the secret string: ");
scanf("%s",input);
if(strcmp(pass,input))
printf("Wrong Password\nAccess Denied\n");
else
printf("Right password\nAccess Granted!!\n");
return 0;
}
when i run the compiled program it is giving wrong output, it suppose to give the right messasge but its giving wrong message. what is the problem here?
below is the output response of the program
professor#CTOS:~/Documents/Bnry/elf32bit/Module3/ch6$ ./crackme
Enter the secret string: Try to hack me
Wrong Password
Access Denied
professor#CTOS:~/Documents/Bnry/elf32bit/Module3/ch6$ ./crackme
Enter the secret string: Try to hack me
Wrong Password
Access Denied
%s in scanf only reads until a white space character. From “Try to hack me”, it only reads “Try”. Use a different method to read the input line, possibly fgets, but be aware that fgets includes the new-line character that terminates the line.
When your program does not work, debug it. Either trace execution with a debugger or insert printf statements to show what it is doing. Inserting printf("The input is %s.\n", input); after the scanf would have revealed the problem.

scanf and printf not printing right values

What is going on here?
The code goes like:
#include<stdio.h>
#include<string.h>
int main()
{
char name[15];
char name_[15];
char answ[1];
printf("What's your name?\n");
scanf("%s", name);
strcpy(name_, name);
printf("Yes / No: ");
scanf("%s", answ);
printf("Hello! %s\n", name_);
printf("You said: %s\n", answ);
return 0;
}
With input "name" and "yes" the expected output is that it says:
Hello! name
You said: yes
Instead I get:
Hello! es
You said: yes
I also tried adding spaces before %s with no results.
So what exactly am I missing here?
answ can contain only 1 character. So currently, the extra character "es" + '\0' gets written into the memory assigned to name_.
So, "es" gets printed.
You've only allocated space for a one-character yes/no answer, but are writing more characters into it.
This results in undefined behaviour.
You need to allocate more space for answ, not forgetting about the NUL terminator.
You have created a classic exploitable buffer overrun but in your code. This is why most modern compilers would advise you to swap sscanf to sscanf_s or similar. As other people have pointed out, you overwrite the next variable on the stack.
I wanted to provide this answer to basically say: never ever use sscanf or any of the obsolete, insecure C functions. Even if this is probably just a toy example, get the practice in to write modern C code. You’ll benefit from this in the long run.

c - scanf not storing input properly

My code looks like this:
int nameFull;
printf("What is your name?\n");
scanf("%d\n", &nameFull); \\up until here it seems to work
printf("Hello %d", nameFull);
return 0;
But my output every time I run the program is "Hello 0" no matter what I input.
Does anyone know how to fix this?
First of all scanf() doesn't emit a prompt so its not a good idea to use any trailing whitespace character in the format string like \n here , It will cause it to read and discard character until next non-whitespace character.
To read a name you can do it like :
char name[50];
scanf("%49s",name); // 49 to limit the buffer input to prevent buffer overrun , this is a security issue.
You should also check the return value of scanf to see if the operation was successful. Personally , I don't prefer using scanf() at all because of various potential problems. It takes as input only what the program author expects it to, not considering other inputs which user might accidentally input. Check out here and here. Also check the scanf() man page
A better and safer method would be use fgets(),
fgets(name,sizeof(name),stdin);
You want to read a string, but you are an integer to store the input. That's not the right approach.
A better aproach would be to use an array of characters, to store the string in it.
char nameFull[100]; // can store up to 100 characters, 99 + 1 for the null-terminator ideally
Now, you could use scanf, like this:
scanf(" %99[^\n]", nameFull);
Note that I used 99, as a guard for not overflowing your array nameFull, if the user inputs too many characters for the size of your array. I didn't use %s, which would stop at a whitespace, and you seem to want to input a full name, which is usually two words and a space in between.
An alternative would be to use fgets(), which provides more safety, like this:
fgets(nameFull, sizeof(nameFull), stdin)
It will read the whole line though and store the trailing newline, while scanf() will read a single string.
Moreover, use the string identifier to print, not the integer one (%s is for string, %d is for integers). Like this:
printf("Hello %d", nameFull);
to this:
printf("Hello %s", nameFull);
as discussed about the string format.
%s reads a string of characters.
%d reads a integer.
So, your correct code will be like following code :
#include <stdio.h>
int main(){
char nameFull[100];
printf("What is your name?\n");
scanf("%99s", nameFull); //to avoid potential buffer overflow
printf("Hello %s\n", nameFull);
return 0;
}
N.B: Check this comment for nice explanation.
Well, int stores a number, a name is not a number. A name is a set of characters (aka strings). So this program would work (no error checking and such since you are in an introductory course):
char name[1024]; // 1024 is more than enough space for a name
scanf("%s", name); // %s reads a string of characters
printf("Hello %s\n", name);
return 0;
You are trying to assign an array of character (commonly referred as string) to an integer variable.
That's not correct.
Just change your variable as such
char nameFull[1024] = {0};
And then use scanf(3) with the appropriate format specifiers for strings, which is %s
scanf("%s", nameFull);
Normally you would check for the return of scanf to know if errors occurs, and in such cases, handle them.
Anyway, I would advice you to use fgets(3) which prevents buffer overflow
char *fgets(char *s, int size, FILE *stream);
fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer. A terminating null byte (aq\0aq) is stored after the last character in the buffer.

Program is not writing to the file after a whitespace is encountered in the string [duplicate]

This question already has answers here:
How do you allow spaces to be entered using scanf?
(11 answers)
Closed 5 years ago.
For Example if I
Input: 'stephen 8108' it outputs
'stephen'
Instead of outputing 'stephen 8108'.
Can someone help me out!
I want the full string to appear in the output.
It reads the string only till the first white space.
Even if i remove the for loop condition it doesn't seem to work it still reads only till the first white space.
#include<fcntl.h>
#include<stdio.h>
#include <unistd.h>
void main()
{
char a[100];
int i,f2,f3,f4;
f2 = creat("a.txt",0666);
f3 = open("a.txt",O_RDWR);
printf("Enter your name & Roll-no\n");
scanf("%s",a);
for(i=0;a[i] != '\0';i++);
write(f3,a,i);
close(f3);
}
This is intended sprintf functionality.
Cite: http://www.cplusplus.com/reference/cstdio/scanf/
Any number of non-whitespace characters, stopping at the first whitespace character found.
One option is to use the negated character matching (quoted from link above):
[^characters] Negated scanset
Any number of characters none of them specified as characters between the brackets.
For example, to match everything excluding a newline:
scanf("%[^\n]", a);
(Full working example below - although please don't take this as necessarily a full and perfect example of reading user input in C++...)
#include<fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
int main()
{
char a[100];
int fp;
fp = open("a.txt", O_CREAT|O_WRONLY|O_TRUNC);
printf("Enter your name & Roll-no\n");
scanf("%[^\n]", a);
write(fp, a, strlen(a));
close(fp);
}
However: I would really encourage you to read the extensive warnings about buffer overflows: https://stackoverflow.com/a/1248017/817132
In short, make sure you don't allow the user to write beyond your (currently 100 character long) memory allocation.
At the current state of your code, the for loop doens't have a body { ... } , so the write and the close operations would be executed only one time.
Also if you want scanf to read a string with spaces you can use %[0-9a-zA-Z ] instead of %s
Regarding the input, there are at least two problems:
The s conversion of scanf() parses until it finds whitespace, it's documented that way.
Without a field width, scanf() will continue parsing when it doesn't find whitespace, overflowing your buffer -> undefined behavior.
The quick fix is to replace scanf("%s",a); with scanf("%99[^\n]",a);. But scanf() is definitely not the best tool to read input, it is for parsing. You seem to just want to read a whole line of input and there is already a function for that: fgets(). Use it in your example like this (include string.h if you want to use this method of stripping the newline character):
fgets(a, 100, stdin);
a[strcspn(a, "\n")] = 0; // remove the newline character if it was read by fgets

How to use scanf for a char array input?

I set a char array of size of 10 and want to check the real size of the input permitted.
I tested
123456789; 1234567890; 123456789123456789
Interestingly, all of them passed and got the right output which are
123456789; 1234567890; 123456789123456789
It confused me a lot because I thought the last two are wrong input.
Does that make sense or is it a compiler difference?
This is the code
#include <stdio.h>
main()
{
char input[10];
scanf("%s", input);
printf(input);
} '
The scanf() with format specifier %s scans the input until a space is encountered. In your case, what you are seeing is undefined behavior.
Your array can hold 10 chars, but you are writing out of its boundaries.
While you are getting an expected answer now, this is not always guarnateed and may instead cause a crash.
It is advisable to use a function such as fgets() takes care of buffer overflow.
You can use
scanf("%9s", input);

Resources