My last prompt answers itself. What do I do? - c

I'm new to C, and I was trying to create a password system with 2 questions. 1. "What is your password?" I prompted the user to answer and recorded the argument. Any input was assigned to the variable. 2."Are you sure? Do you want this password? Enter Yes or No." It would decide whether to use the answer or discard it. Everything was working smoothly until this part. I couldn't type Yes or No. It automatically assumed that I had typed yes and saved it. Can somebody please give me some advice?
#include <stdio.h>
int
main ()
{
char password;
printf ("Hello User.");
printf ("Please type in your password:");
scanf ("%d", & password);
char answer;
printf ("\nAre you sure? Do you want this password? Enter Yes or No: \n");
scanf ("%c", answer);
printf ("\nAnswer is %c");
if (answer == 'Yes')
printf ("Confirmed.");
else (answer == 'No');
printf ("OK. Thank you.");
password = 0;
return 0;
}

As noted in the comments, you likely didn't intend to store a password in a single character. Nor did you likely intend to scanf the password as an integer using, which is what you're saying with %d.
You may want to use getline instead to read an entire line, and store it in password if you declare it as char array.
Let's say you gave it room for 100 chars.
char password[100];
You might read your password in with:
getline(password, 100, stdin);
You can do the same for the second question, but should always use strcmp to compare strings in C. When the two strings are equal, the return value is 0. Be careful as this is opposite of the way that "true" is usually represented by integers in C.
if (strcmp(response, "yes") == 0) {
...
}
Hopefully these tips will point you in the right direction.

Research and study the functions and syntax.
#include <stdio.h>
#include <string.h>
//function: Clears password
void clearPassword(char p[])
{
for(int i = strlen( p ); i>=0; i--)
{
p[i]='\0';
}
}
int main ()
{
char password[101]; //C version of a String
char line[100]; //C version of a String
char answer;
printf ("Hello User.");
printf ("Please type in your password: ");
fgets(line, sizeof(line), stdin); // read input
sscanf(line, "%s", &password); // store password
printf ("\nAre you sure? Do you want this password? Enter Y or N: \n");
fgets(line, sizeof(line), stdin); //read input
sscanf(line, "%c", &answer); // store answer
printf ("\nAnswer is %c \n", answer); // print answer
if (answer == 'Y') //
printf ("Confirmed.");
else
{
clearPassword(password);
printf ("OK. Thank you.");
}
return 0;
}

Related

C Program - How to deny any non-numerical input

I've just started learning the language of C, and would love your help in cleaning up / simplifying my code if you know a better way to reach the following.
I want a program to ask for a number, and if that is found then proceed to print and end, however if anything else is put in (e.g. a letter key), then I want the program to loop asking for a number until one is given.
I started off by using a simple scanf input command, but this seemed to go into an infinite loop when I tried to check if a valid number (as we define them) was put in.
So instead I have ended up with this, from playing around / looking online, but I would love to know if there is any more efficient way!
//
// Name & Age Program
// Created by Ben Warren on 1/3/18.
//
#include <stdio.h>
int main (void)
{
//Setting up variables
int num;
char line[10]; /* this is for input */
//Collecting input
printf("Please enter any number? \t");
scanf("%d", &num);
//If Invalid input
while (num==0)
{
printf("\nTry again:\t");
fgets(line, 10, stdin); //turning input into line array
sscanf(line, "%d",&num); //scaning for number inside line and storing it as 'num'
if (num==0) printf("\nThat's not an number!");
}
//If Valid input
{
printf("\n%d is nice number, thank you! \n\n", num);
*}*
return 0;
}
Instead of checking if the value is different to 0, check the return value of
sscanf. It returns the number of conversions it made. In your case it should be 1. Unless the return value is 1, keep asking for a number.
#include <stdio.h>
int main(void)
{
int ret, num;
char line[1024];
do {
printf("Enter a number: ");
fflush(stdout);
if(fgets(line, sizeof line, stdin) == NULL)
{
fprintf(stderr, "Cannot read from stdin anymore\n");
return 1;
}
ret = sscanf(line, "%d", &num);
if(ret != 1)
fprintf(stderr, "That was not a number! Try again.\n");
} while(ret != 1);
printf("The number you entered is: %d\n", num);
return 0;
}
That is not a bad approach for someone new to C. One small improvement would be to actually check the return value of scanf(), since it returns the number of arguments successfully retrieved. Then you could get away from relying on num being 0 to indicate the input was valid. Unless you do want to specifically flag 0 as invalid input.
int ret = scanf("%d", &num);
ret == 1 would mean an integer was succesffully read into num, ret == 0 would mean it was not.
Consider using strtol to parse a string for a long int. This also allows you to detect trailing characters. In this example if the trailing character is not a newline, the input can be rejected. strtol can also detect overflow values. Read the documentation to see how that works.
#include <stdio.h>
#include <stdlib.h>
int main (void)
{
//Setting up variables
long int num = 0;
char line[40] = ""; /* this is for input */
char *parsed = NULL;
printf("Please enter any number? \t");
fflush ( stdout);
while ( fgets(line, 40, stdin))
{
parsed = line;//set parsed to point to start of line
num = strtol ( line, &parsed, 10);
if ( parsed == line) {//if parsed equals start of line there was no integer
printf("Please enter a number? \t");
printf("\nTry again:\t");
fflush ( stdout);
continue;
}
if ( '\n' != *parsed) {//if the last character is not a newline reject the input
printf("Please enter only a number? \t");
printf("\nTry again:\t");
fflush ( stdout);
}
else {
break;
}
}
if ( !parsed || '\n' != *parsed) {
fprintf ( stderr, "problem fgets\n");
return 0;
}
printf("\n%ld is nice number, thank you! \n\n", num);
return 0;
}
0 (zero) is a number...
But I see what you want to do...
You can check for a valid number, using isdigit or a combination of similar functions
I think its also important to follow the advice of other answers to use the return value from scanf using code such as:
int ret = scanf("%d", &num);
and examining ret for success or failure of scanf.

how do I make sure that the user is entering a integer in c?

I want the program to ask the user for a number, and if the user does not enter a number the program will say "input not a integer."
Thx for the help guys!
I propose this (it doesn't handle integer overflow):
#include <stdio.h>
int main(void)
{
char buffer[20] = {0}; // 20 is arbitrary;
int n; char c;
while (fgets(buffer, sizeof buffer, stdin) != NULL)
{
if (sscanf(buffer, "%d %c", &n, &c) == 1)
break;
else
printf("Input not integer. Retry: ");
}
printf("Integer chosen: %d\n", n);
return 0;
}
EDIT: Agreed with chux suggestions below!
One possible way: use scanf() function to read the input. It returns the number of items it successfully read.
Another way: read the input as string with scanf() of fgets() and then try to parse it as integer.

Comparing strings in C using strcmp

I am trying to learn to program in C but am having trouble with manipulating strings as C treats strings as arrays.
My aim was to make a program that stores the users first name and surname.
Here is my progress:
#include <stdio.h>
int main(int argc, const char * argv[]) {
//defining the variables
char first_name[100];
char surname[100];
char ch[2];
// Asking for the first name and storing it
printf("What's your first name?\n");
scanf("%s", first_name);
// Prints the first name
printf("Hey %s!\n",first_name);
//Asks the user if they want to store their surname
printf("Would you like to tell me your second name? This is optional so type 'Y' for yes and 'N' for no.\n");
scanf("%s", ch);
//validate if they want to store it or not
if (ch == "Y"){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
return (0);
}
However, with this code, I get an error because my IDE(xCode) tells me to use the strcmp function. I then edited the code to become this:
if (strcmp(ch, "Y")){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
However variable ch is not a literal and so is not comparable.
Sidenote
I did try to compare two literals too, just to see how it works:
char *hello = "Hello";
char *Bye = "Bye";
if (strcmp(hello, Bye)){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
But even this gave an error:
Implicitly declaring library function 'strcmp' with type 'int (const *char, const *char)'
I believe I am not able to do this due to my lack of experience so it would be much appreciated if you could help me understand what I'm doing wrong and how I can fix the problem.
You need to include the appropriate header:
#include <string.h>
Also note that your desired logic probably calls for:
if (!strcmp(hello, Bye))
Instead of:
if (strcmp(hello, Bye))
Since strcmp returns 0 in case of equality.
There are several issues you should correct concerning how you handle input with scanf. First always, always validate the number of successful conversions you expect by checking the return for scanf. Next, as mentioned in the comment, there is NO need to include <string.h> in your code to make a one-letter comparison. Use a character comparison instead of a string comparison. Lastly, always limit your input to the number of characters available (plus the nul-terminating character.
Putting the bits together, you could do something like the following:
#include <stdio.h>
#define MAXN 100
int main (void) {
char first_name[MAXN] = "", surname[MAXN] = "";
int ch;
printf ("What's your first name?: ");
if (scanf ("%99[^\n]%*c", first_name) != 1) {
fprintf (stderr, "error: invalid input - first name.\n");
return 1;
}
printf ("Hey %s!\n", first_name);
printf("Enter surname name? optional (Y/N) ");
if (scanf("%c%*c", (char *)&ch) != 1) {
fprintf (stderr, "error: invalid input - Y/N\n");
return 1;
}
if (ch != 'y' && ch != 'Y') /* handle upper/lower case response */
return 1;
printf ("Enter your surname?: ");
if (scanf (" %99[^\n]%*c", surname) != 1) {
fprintf (stderr, "error: invalid input - surname\n");
return 1;
}
printf ("\nYour whole name is : %s %s\n", first_name, surname);
return 0;
}
Example Use/Output
$ ./bin/firstlast
What's your first name?: David
Hey David!
Enter surname name? optional (Y/N) Y
Enter your surname?: Rankin
Your whole name is : David Rankin
Look it over and let me know if you have any questions.
There are two problems here. Firstly you need to see what value is returned by the strcmp and secondly you must use the approprate hedder.
You must use:
#include <string.h>
Secondly, you must edit your if-else statement so it is like this:
if (strcmp(ch, "Y") == 0){
printf("What is your surname?\n");
scanf("%s", surname);
printf("Your whole name is %s %s", first_name, surname);
}
We do this because the strcmp function returns a negative value if ch is smaller than "Y", or a positive value if it is greater than "Y" and 0 if both strings are equal.

fprintf in do while loop wrote only one line in file C

I don't know why it is writing only one line in my file
void foo()
{
int ID;
char answer;
FILE *input = fopen("Dane.txt", "w");
do
{
printf("Give ID: ");
scanf("%d",&ID);
fprintf(input, "%d\n", ID);
printf("Exit? y/n ");
scanf("%s", &answer);
fflush(NULL);
}
while (answer != 'n');
fclose(input);
}
Output (in file) is only first ID number which I write on console. But where are others?
EDIT: ok I got it. The error was in char answerand it should be char answer[2] and ending while should be while(answer[0] != ...). Before it the program read only one character - the line end. When i hit e.g. "n ENTER" it take only ENTER. Now it take the first char from tab i.e. "n". Thank everybody for help
You are doing some logical mistake. You are asking whether exit or not. If user does not want to exit, then he would press n. So, to continue the loop, the answer should be equal to n, right?
Modified version of your program:
void foo()
{
int ID;
char answer;
FILE *input = fopen("Dane.txt", "w");
do
{
printf("Give ID: ");
scanf("%d",&ID);
fprintf(input, "%d\n", ID);
printf("Exit? y/n ");
scanf(" %c", &answer);
fflush(NULL);
}
while (answer == 'n');
fclose(input);
}
answer has only one space to read and it isn't capable to store string whose length is 1 character or longer.
This won't affect the result, but using input for output file pointer is confusing.
The conditio in while is unnatural.
Try this:
#include <stdio.h>
void foo();
int main() {foo(); return 0;}
void foo()
{
int ID;
char answer[4];
FILE *output = fopen("Dane.txt", "w");
if (output == NULL) return;
do
{
printf("Give ID: ");
if (scanf("%d",&ID) != 1) break;
fprintf(output, "%d\n", ID);
printf("Exit? y/n ");
if (scanf("%3s", answer) != 1) break;
fflush(NULL);
}
while (answer[0] != 'y');
fclose(output);
}
When I ran your function, I got all three numbers I entered in the file:
$ ./a.out
Give ID: 25
Exit? y/n y
Give ID: 33
Exit? y/n y
Give ID: 10
Exit? y/n n
$ cat Dane.txt
25
33
10
However, your question is backwards. You ask, "Exit? y/n" and then exit if the answer is "n" ("no"). The question should be "Continue? y/n", so that when the user answers in the affirmative, it continues.
Also, naming your output filehandle "input" is backwards, and as others have mentioned, your answer variable should be a character array of at least 2 characters, as char answer[2];.

scanf not responding?

Ive recently begun learning C and am trying to write a password data protection program. Im writing a function which should test to see if a file, password.txt exists if it doesnt it will get a null value and then ask the user to set a master password and to repeat. However it doesnt allow the user to repeat the password. Any tips? - Cheers (Keep in mind just C not C++)
/*Headers*/
#include <stdio.h>
#include <stdlib.h>
#define MAX_LENGTH 99
int main(void){
/*Variable Declaration*/
char password[] = "Lakaka";
masterPassword();
printf("Welcome to Fort-Knox.");
getchar();
return 0;
}
int masterPassword(void){
/*Password Comparison Variables*/
char password[MAX_LENGTH];
char password1[MAX_LENGTH];
FILE*fp;
if (fp == NULL){
printf("Choose a master password:\n");
scanf("%c", password);
printf("Please repeat password:\n");
scanf("%c", password1);
if (password == password1){
printf("Password Accepted.");
fp = fopen("password.txt", "w+");
printf("File Created");
fclose(fp);
return 0;
}
}
}
Use %s not %c as format specifier, when reading a string. %c only reads a single character.
Your formatting specifier is wrong.
This is also wrong:
if (password == password1)
this will only compare the arrays converted to pointers. You need to compare character-by-character, by calling strcmp():
if( strcmp(password, password1) == 0 )
{
printf("match!\n");
}
use "%s" instead of "%c"
%c is for only 1 character
%s is for string
scanf("%s", password);
scanf("%s", password1);
you need to do
scanf("%s", password);
and to compare use :
strncmp(password,password1,MAX_LENGTH)
it´s always more safe :)...

Resources