Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am creating a program that requires the user to create a password that has at least one symbol, one uppercase letter, one lowercase letter, and a digit. However, I got so many errors. I fixed most of them but there are still a few I can't seem to figure out. It would be easier to just send a screenshot.
And here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> //To use isupper, isalpha, and isdigit
int main() {
//Declaring the variables
char userPassword;
int i;
int digit = 0;
int upper = 0;
int lower = 0;
int letter = 0;
int symbol = 0;
//User enters password
printf("Please create a password including at least 1 number, 1 uppercase letter, and one symbol: ");
scanf(" %c", &userPassword);
//strlen makes sure password is not less than 8 characters
if (strlen(userPassword) < 8) {
printf("INVALID PASSWORD.");
}
else {
//A for loop that checks if all the conditions are met
for (i = 0; i = 20; i++) {
//Makes sure password has a letter
if (isalpha(userPassword[i])) {
letter++;
}
//Makes sure password has an uppercase letter
else if (isupper(userPassword)) {
upper++;
}
//Makes sure password has a lowercase letter
else if (islower(userPassword)) {
lower++;
}
//Makes sure password has a digit
else if (isdigit(userPassword)) {
digit++;
}
//Makes sure password has a symbol
else if (userPassword == '!' || userPassword == '#' || userPassword == '#' || userPassword == '$' || userPassword == '%' || userPassword == '^' || userPassword == '&' || userPassword == '*' || userPassword == '(' || userPassword == ')' || userPassword == '-' || userPassword == '+' || userPassword == '_');
symbol++;
}
}
//If the password has all of them, it can be created
if (digit == 0 && upper == 0 && lower == 0 && letter == 0 && symbol == 0) {
printf("PASSWORD CREATED.");
}
else {
printf("INVALID PASSWORD.");
}
return 0;
}
Any help would be appreciated!
First of all, we need to address some error in syntax as well as logic. The following things are changed:
userPassword should be a character array. I assume you have chosen maximum length of password as 20 by looking at your for loop. Therefore, declare it as char userPassword[20].
The condition in the for loop is changed to for (i = 0; i < 20; i++).
There was a logical mistake in the algorithm to check the type of the character. Therefore, I have replaced the else if constructs to if.
Character array in C, should be scanned using the %s format specifier.
Also, don't forget to include string.h for the strlen() function.
Have a look a the corrected code:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> //To use isupper, isalpha, and isdigit
#include <string.h>
int main() {
//Declaring the variables
char userPassword[20]; //Assuming maximum length of password is 20.
int i;
int digit = 0;
int upper = 0;
int lower = 0;
int letter = 0;
int symbol = 0;
//User enters password
printf("Please create a password including at least 1 number, 1 uppercase letter, and one symbol: ");
scanf(" %s", userPassword);
//strlen makes sure password is not less than 8 characters
if (strlen(userPassword) < 8) {
printf("INVALID PASSWORD.");
}
else {
//A for loop that checks if all the conditions are met
for (i = 0; i < 20; i++) {
//Makes sure password has a letter
if (isalpha(userPassword[i])) {
letter++;
}
//Makes sure password has an uppercase letter
if (isupper(userPassword[i])) {
upper++;
}
//Makes sure password has a lowercase letter
if (islower(userPassword[i])) {
lower++;
}
//Makes sure password has a digit
if (isdigit(userPassword[i])) {
digit++;
}
//Makes sure password has a symbol
if (userPassword[i] == '!' || userPassword[i] == '#' || userPassword[i] == '#' || userPassword[i] == '$' || userPassword[i] == '%' || userPassword[i] == '^' || userPassword[i] == '&' || userPassword[i] == '*' || userPassword[i] == '(' || userPassword[i] == ')' || userPassword[i] == '-' || userPassword[i] == '+' || userPassword[i] == '_'){
symbol++;
}
}
//If the password has all of them, it can be created
if (digit > 0 && upper > 0 && lower > 0 && letter > 0 && symbol > 0) {
printf("PASSWORD CREATED.");
}
else {
printf("INVALID PASSWORD.");
}
}
return 0;
}
Test Cases:
Input 1: Rt%oi45u#
Output: PASSWORD CREATED.
Input 2: Rt%oiu#
Output: INVALID PASSWORD.
At a quick glance:
As the warning says, you'll want #include <string.h> to include the definition of strlen.
You declare userPassword as only one character, not as an array of characters (e.g. userPassword[32]) (which can hold a string up to 31 characters in length).
You should use scanf("%s", userPassword) (or preferably fgets with a maximum length) to read strings.
Your for loop condition is wrong; for (i = 0; i < strlen(userPassword); i++) { is likely what you're looking for.
All but the first if(isalpha...) condition are wrong; you're not indexing the password in the rest (userPassword[i] c.f. userPassword)
There's an extraneous ; after the special-character check, so symbol gets incremented every time
The check for whether all of the required character types exist is inverted; it'd create the password when none of the conditions match.
Your code have 3 errors.
You must include string.h for strlen function.
%c can only cover character. replace %c to %s in scanf(" %c", &userPassword);
And declare userPassword as char array. replace char userPassword[32]
Related
#include <stdio.h>
#include <string.h>
#define CHAR_SIZE 35
//Function to remove white space
char *remove_white_spaces(char *str)
{
int i = 0, j = 0;
while (str[i])
{
if (str[i] != ' ')
str[j++] = str[i];
i++;
}
str[j] = '\0';
return str;
}
void main()
{
int i = 0;
char str[CHAR_SIZE];
printf("\nKey in input: ");
fgetchar();
fgets(str , CHAR_SIZE, stdin);
//Remove white space
remove_white_spaces(str);
printf("%s",str);
//for (i = 0; str[i] != '\0'; ++i);
//printf("Length of the string: %d", i);
if (str[i] == '0' || str[i] == '1' )
{
printf("CORRECT");
}
else
{
printf("Wrong Input");
}
}
I want to check whether the user has type in the correct input. For example, I have key in 0 01111110 10100000000000000000000. After removing the white space, the str input became 00111111010100000000000000000000. From this str, I want to check that the user has only key in 0 and 1. The output of the result I got was correct which is shown below1.
Output of result
However, when the user key in another value including 0 and 1. The output I suppose to get is the wrong input. But I obtained Correct as the result which is shown below2.
Output of result
Additional question, How do I implement an if statement that the str has to only have 32 characters to continue otherwise it has to break and the user key has to key in 32 characters only. Can I do it in a while loop instead of an if statement so that the user would not need to run the code again?
You could use strtok to extract your characters. Also there's a flaw in your logic. it should be if (str[i] == '0' || str[i] == '1' to check if the value is '0' OR '1'. Here's a sample implementation you could refer to:-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHAR_SIZE 100
int main()
{
char str[CHAR_SIZE];
printf("\n Key in value: ");
getchar();
fgets(str, CHAR_SIZE, stdin);
char *tok;
tok = strtok(str, "\n");
int i = 0;
tok++; //skip the first character which is a space
while (*tok != 0x00)
{
if (*tok <= 0x31 && *tok >= 0x30)
tok++;
else
{
printf("Wrong number input ==> %c \n", *tok);
break;
}
}
}
initialize i:
putting the equivalent of C's
int i = 0;
in your prog lang before entering the while loop should do the job.
First of all, you are checking that str[i] should be equal to 0 and equal to 1 – and that doesn't make any sense, because an element in the array can be only one value, 0 or 1; so, you should test if (str[i] == '0' || str[i] == '1').
And, before that, you should initialize i: int i = 0.
Edit you must loop over elements of the string
int check = 0;
while (str[i] != '\0')
{
if (str[i] == '0' || str[i] == '1')
i++;
else {
check = 1;
break;
}
}
if (check == 0){
print("CORRECT");
}
else {
printf("WRONG INPUT");
}
I am on Windows and have tried the following code to mask password input:
#include <stdio.h>
#include <conio.h>
int main() {
int i = 0;
char ch, password[13];
printf("\nEnter Password (Upto 12 chars.): ");
while (i < 12) {
ch = getch();
if (ch == ' ') {
--i;
} else if (ch == '\b') {
printf("\b \b");
i -= 2;
} else if (ch == '\r')
break;
else {
password[i] = ch;
printf("*");
}
++i;
}
password[i] = '\0';
printf("\nPassword: %s",password);
return 0;
}
The problem with above code is that when I have inputted no characters and I press backspace then the printed string Enter Password (Upto 12 chars.): gets its characters erased one by one. This I was able to work around by doing this Enter Password (Upto 12 chars.):\n and now it won't delete its characters. But there is another problem and that is whenever I try to close the terminal by pressing Alt+F4 the two keystrokes get considered input by getch() and I get two characters returned and displayed. I know it is my fault as the else part takes anything except \r,\b and white-space but I want help fixing it.
What I want is to be able to mask password input without any of the above problems. I have used MySQL Command-line client before and it asks for password input just fine. Anything like that or close to that would be appreciated.
I should mention this is for a University project.
Any help is appreciated
I fixed my own code. Took some inspiration from some old C++ code (not copy pasta).
It ignores whitespace, Esc key, function and arrow keys, works properly on backspace, and breaks out of the loop on hitting Tab or Enter. And now it doesn't delete characters from printf() string when hitting backspace on empty input.
The trick is to only assign input when all other if and else if conditions are not met and increment the counter in that else block only. And then when the loop ends put a '\0' at the last index of the string.
Here is the code:
#include <conio.h>
#include <stdio.h>
#define PASSWORD_LENGTH 12
int main() {
int i = 0;
char password[PASSWORD_LENGTH + 1];
int ch;
printf("\nEnter Password (Upto 12 chars.): ");
while (i < PASSWORD_LENGTH) {
ch = getch();
if (ch == ' ' || ch == 27) {
continue;
} else if (ch == '\b') {
if (i > 0) {
printf("\b \b");
--i;
} else {
continue;
}
} else if (ch == '\r' || ch == '\t') {
break;
} else if (ch == 0 || ch == 224) {
ch = getch();
continue;
} else {
password[i++] = ch;
printf("*");
}
}
password[i] = '\0';
printf("\n,%s,", password); //this can be removed as it is only for displaying output
return 0;
}
Q : Write a program to count the number of occurrences of any two vowels in succession in a line of text. For example the following sentence :
"Please read the application and give me gratuity"
Such occurrences in the sentence are :- "ea" , "ea" , "io" , "ui". Ultimately the question is to count the number of such occerrences in the line which is a user input string.
Problem : My program is just recieve a line but did not give any output.
It's my first question in stackoverflow. I am a beginner in programming.
My code:
# include <stdio.h>
int main () {
char line[100];
printf("\nEnter a line\n");
gets(line);
//printf("You entered : %s\n", line);
char A,E,I,O,U,a,e,J,o,u;
A = 'A';
E = 'E';
I = 'I';
O = 'O';
U = 'U';
a = 'a';
e = 'e';
J = 'i';
o = 'o';
u = 'u';
int occurence =0,i =0 ;
while (line[i] =! '\0'){
if((line[i] == A || E || I || O || U || a || e || J || o || u) && (line[i+1] == a || e || J || o || u)){
occurence++;
}
i++;
}
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurence);
return 0;
}
Your code has multiple issues, some of which are:
You use gets to read the string. This function is now at least deprecated (I think it was even removed from recent versions of the standard library) because it is unsafe. Use fgets instead!
You use the || operator wrong - this was already pointed out in mediocrevegetable1's comment.
You could use a code similar to this one to solve your problem. The code contains comments, so it should be easy to understand. However, if this is a homework or project for school, do NOT use this exact code, as this would most likely be considered plagiarism!
#include <stdio.h>
#include <ctype.h>
#define STRLEN 100
int main () {
char line[STRLEN];
char* ch;
char incrementIfVowel;
int occurences;
/* Read line */
printf("\nEnter a line\n");
fgets(line, STRLEN, stdin);
/* Init variables */
incrementIfVowel = 0;
occurences = 0;
/* Iterate through characters */
for (ch = line; *ch != '\0'; ch++) {
/* Test if the current character is a vowel. Three cases can occur: */
if (toupper(*ch) == 'A' || toupper(*ch) == 'E' || toupper(*ch) == 'I' || toupper(*ch) == 'O' || toupper(*ch) == 'U') {
if (incrementIfVowel == 1) {
/* Case 1: The current character is a vowel, and its predecessor was also a vowel */
incrementIfVowel = 0;
occurences++;
}
else {
/* Case 2: The current character is a vowel, but its predecessor was not a vowel or it was the second vowel in a row */
incrementIfVowel = 1;
}
}
else {
/* Case 3: The current character is not a vowel */
incrementIfVowel = 0;
}
}
/* Print result */
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurences);
return 0;
}
There are 3 main issues with your code:
gets(line);
gets doesn't check the length of the buffer and for this reason, is susceptible to buffer overflows. gets had been deprecated since C99 and was removed in C11. You're probably compiling with an older version of the standard; I'd suggest you switch to newer versions. As for an alternative, see fgets.
while (line[i] =! '\0'){
=! is a typo. Replace it with !=
if((line[i] == A || E || I || O || U || a || e || J || o || u) && (line[i+1] == a || e || J || o || u))
This will always evaluate to true because || doesn't chain like that. Ideally, you should put this in a function:
_Bool is_vowel(char ch)
{
return toupper(ch) == 'A' || toupper(ch) == 'E' || toupper(ch) == 'I' || toupper(ch) == 'O' || toupper(ch) == 'U';
}
toupper is defined in <ctype.h> so be sure to include that. You could also shorten this behemoth of a line with return strchr("AEIOUaeiou", ch), but if you haven't used strchr and are not comfortable with using it yet, that's okay.
Modifying only the incorrect parts, your final code will can look something like this:
#include <stdio.h>
#include <ctype.h>
_Bool is_vowel(char ch)
{
return toupper(ch) == 'A' || toupper(ch) == 'E' || toupper(ch) == 'I' || toupper(ch) == 'O' || toupper(ch) == 'U';
}
int main () {
char line[100];
printf("\nEnter a line\n");
fgets(line, sizeof line, stdin);
int occurence = 0, i = 0;
while (line[i] != '\0') {
if(is_vowel(line[i]) && is_vowel(line[i + 1]))
occurence++;
i++;
}
printf("Number of occurence of any two vowels in succession in the line is : %d\n", occurence);
return 0;
}
An example of running this:
Enter a line
Please do something about the bee hive and then eat some meat
Number of occurence of any two vowels in succession in the line is : 5
(5 because Pl<ea>se do something ab<ou>t the b<ee> hive and then <ea>t some m<ea>t)
scanf("%c%c%c%c", &var1, &var2, &var3, &var4);
if ((var1 != 'f' || '+' || '-' || '[' || ']') ||
(var2 != 'f' || '+' || '-' || '[' || ']') ||
(var3 != 'f' || '+' || '-' || '[' || ']') ||
(var4 != 'f' || '+' || '-' || '[' || ']'))
printf("Invaild input\n");
this is my code,i want user to enter 4 variables with space between each one and the output to be invaild if the input is diffrent from any of this chars.right now no matter what i enter into the code the "invalid input" is the output. is there something wrong in here?
The main reason why it does not work is because your conditions like (var1 != 'f' || '+' || '-' || '[' || ']') do something completely different than you might think. An expression like (anyBooleanValue || '+') will always return true, regardless what the value of anyBooleanValue is. This is because the RHS operand '+' is a character literal, i.e. an integral value representing (very likely) the ASCII-code of character '+'. Any integral value other than 0 is treated as true, so it reads like anyBooleanValue || true, which obviously is always true.
So you actually would have to write something like if (var1 != 'f' && var1 != '+' && ... as #WhozCraig mentioned.
But actually you have the same code appearing again and again, and such cases are usually handled by loops. And the test of whether a character appears in a set of possible characters can be solved easily with function strchr, which returns a pointer to the first occurrence of the character in question or NULL, if the character does not occur. The following code illustrates this:
int main() {
#define nvars 4
char vars[nvars];
int i;
for (i=0; i<4; i++) {
scanf(" %c", &vars[i]);
if (strchr("f+-[]",vars[i]) == NULL) { // char not found?
break;
}
}
if (i<4) {
printf("Invaild input\n");
} else {
printf("valid.\n");
}
}
Note further the leading blank in scanf(" %c", which is for consuming white spaces before the actual character.
#Stephan Lechner well identified the problems with OP's code and a good solution. Below is an alternative solution to check if a character is one of several characters in one step. Use a look-up table.
#include <stdio.h>
#include <stdbool.h>
#include <limits.h>
int mango_test(unsigned char ch) {
// If char is not too big
#if UCHAR_MAX < 1024
static const bool good[UCHAR_MAX + 1] = { //
['f'] = 1, ['+'] = 1, ['-'] = 1, ['['] = 1, [']'] = 1}; // look-up table
return good[ch];
#else
char *s = strchr("f+-[]", ch);
return s && ch; // Found in list and not the null character.
#endif
}
int main(void) {
for (int ch = SCHAR_MIN; ch <= UCHAR_MAX; ch++) {
int found = mango_test(ch);
if (found)
printf("Found %d <%c>\n", ch, ch);
}
}
Output
Found 43 <+>
Found 45 <->
Found 91 <[>
Found 93 <]>
Found 102 <f>
Is there an easy way to call a C script to see if the user inputs a letter from the English alphabet? I'm thinking something like this:
if (variable == a - z) {printf("You entered a letter! You must enter a number!");} else (//do something}
I want to check to make sure the user does not enter a letter, but enters a number instead. Wondering if there is an easy way to pull every letter without manually typing in each letter of the alphabet :)
It's best to test for decimal numeric digits themselves instead of letters. isdigit.
#include <ctype.h>
if(isdigit(variable))
{
//valid input
}
else
{
//invalid input
}
#include <ctype.h>
if (isalpha(variable)) { ... }
isalpha() will test one character at a time. If the user input a number like 23A4, then you want to test every letter. You can use this:
bool isNumber(char *input) {
for (i = 0; input[i] != '\0'; i++)
if (isalpha(input[i]))
return false;
return true;
}
// accept and check
scanf("%s", input); // where input is a pointer to a char with memory allocated
if (isNumber(input)) {
number = atoi(input);
// rest of the code
}
I agree that atoi() is not thread safe and a deprecated function. You can write another simple function in place of that.
Aside from the isalpha function, you can do it like this:
char vrbl;
if ((vrbl >= 'a' && vrbl <= 'z') || (vrbl >= 'A' && vrbl <= 'Z'))
{
printf("You entered a letter! You must enter a number!");
}
The strto*() library functions come in handy here:
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#define SIZE ...
int main(void)
{
char buffer[SIZE];
printf("Gimme an integer value: ");
fflush(stdout);
if (fgets(buffer, sizeof buffer, stdin))
{
long value;
char *check;
/**
* strtol() scans the string and converts it to the equivalent
* integer value. check will point to the first character
* in the buffer that isn't part of a valid integer constant;
* e.g., if you type in "12W", check will point to 'W'.
*
* If check points to something other than whitespace or a 0
* terminator, then the input string is not a valid integer.
*/
value = strtol(buffer, &check, 0);
if (!isspace(*check) && *check != 0)
{
printf("%s is not a valid integer\n", buffer);
}
}
return 0;
}
You can also do it with few simple conditions to check whether a character is alphabet or not
if((ch>='a' && ch<='z') || (ch>='A' && ch<='Z'))
{
printf("Alphabet");
}
Or you can also use ASCII values
if((ch>=97 && ch<=122) || (ch>=65 && ch<=90))
{
printf("Alphabet");
}
int strOnlyNumbers(char *str)
{
char current_character;
/* While current_character isn't null */
while(current_character = *str)
{
if(
(current_character < '0')
||
(current_character > '9')
)
{
return 0;
}
else
{
++str;
}
}
return 1;
}
You can implement the following function that returns a boolean, it checks whether the input is only composed by characters and not numbers, it also ignores spaces. Note that it supposes that the input in collected by fgets and not scanf. You should only change the while condition if you want to use another input method.
bool is_character(char text[])
{
bool just_letters;
just_letters = true;
while((text[i] != '\n') && (just_letters == true))
{
if ((text[i] >= 'A' && text[i] <= 'Z') || (text[i] >= 'a' && text[i] <= 'z') || text[i] == 32)
{
just_letters = true;
}
else
{
just_letters = false;
}
}
return just_letters;
}