I want to make a program to check if there are any numbers, uppercase and lowercase letters in my password.But,an error about 'lvalue' will occur when this code is executed. What is the reason?
#include <stdio.h>
#include <string.h>
int main(void)
{
char passwd[99];
printf("make a password:");
gets_s(passwd,99);
int num_count = 0, up_count = 0, down_count = 0;
while(1)
{
for (int i = 0; passwd[i] != NULL; i++)
{
if ('0' <= passwd[i] && passwd[i] <= '9')
num_count++;
else if ('a' <= passwd[i] && passwd[i] <= 'z')
{
down_count++;
}
else if ('A' <= passwd[i] && passwd[i] <= 'Z')
{
up_count++;
}
}
if (num_count == 0 || up_count == 0 || down_count = 0)
printf("make the password again!");
else
{
break;
}
}
getch();
return 0;
}
num_count == 0 || up_count == 0 || down_count = 0
should be
num_count == 0 || up_count == 0 || down_count == 0
To explain the error, the statement you have is equivalent to the following:
( num_count == 0 || up_count == 0 || down_count ) = 0
An expression that can be found on the left-hand side of an assignment is called an lvalue, and the expression in parens is not a valid lvalue.
Related
I want to take input as a string and evaluate if it is a valid password. The password is valid if it has numbers, capital and small alphabets, and a length of at least 7 characters. Also, when all these requirements are satisfied, the output should be "Strong", else "Weak". Code:
#include<stdio.h>
#include<string.h>
#define N 20
int main()
{
char pass[N];
int i, x=0, p;
printf("Enter a password: ");
scanf("%s", &pass);
if(strlen(pass)>=7)
{
p=strlen(pass);
for (i = 0; i < p; i++)
{
if ((pass[i] >= 'a' && pass[i] <= 'z') || (pass[i] >= 'A' && pass[i <= 'Z') || (pass[i] >= '0' && pass[i] <= '9'))
printf("Sucess! ");
}
}
else
printf("Try Again..");
return 0;
}
Somethings are not working like: 1. After execution, it prints "Sucess!!" multiple times.. 2. In the inner if block, when i replace || with &&, it didn't print anything.
Please help.
You could change this section of code:
p=strlen(pass);
for (i = 0; i < p; i++)
{
if ((pass[i] >= 'a' && pass[i] <= 'z') || (pass[i] >= 'A' && pass[i <= 'Z') || (pass[i] >= '0' && pass[i] <= '9'))
printf("Sucess! ");
}
... to something like this:
int lower_case_count = 0;
int upper_case_count = 0;
int digit_count = 0;
p=strlen(pass);
for (i = 0; i < p; i++) {
if (pass[i] >= 'a' && pass[i] <= 'z') ++lower_case_count;
if (pass[i] >= 'A' && pass[i] <= 'Z') ++upper_case_count;
if (pass[i] >= '0' && pass[i] <= '9') ++digit_count;
}
if (lower_case_count > 0 && upper_case_count > 0 && digit_count > 0) {
printf("Strong\n");
}
In the loop you just want to count how many of each type of characters is present.
Once the loop is done, you can check whether all requirements are satisfied and take appropriate action.
You made me thinking and I came up with this rather simple solution - two series of ifs, one wrapped within a while loop. It checks for lower and uppercase, numbers and special characters, reporting the exact error a user had eventually made.
//A program for password validation
#include <stdio.h>
#include <ctype.h>//for islower(), isupper(), isdigit() and ispunct()
#include <string.h>//for strlen()
int main(void)
{
char pass[30];
printf("Enter your password: ");
scanf("%[^\n]s", pass);//so that password may contain space char
int i = 0,
lower_count = 0,
upper_count = 0,
digit_count = 0,
punct_count = 0;
int length = strlen(pass);
//loop goes through the password as array
while (pass[i]) {
if(islower(pass[i]))//if there is lowercase
lower_count++;
if(isupper(pass[i]))//if there is uppercase
upper_count++;
if (isdigit(pass[i]))//if there is a number
digit_count++;
if (ispunct(pass[i]))//if there is a special chars
punct_count++;
i++;
}
if(strlen(pass) < 8)
{
printf("The password must have at least 8 chars\n");
return 1;
}
if(lower_count == 0)
{
printf("You need lowercases\n");
}
if(upper_count == 0)
{
printf("You need an uppercase\n");
}
if(digit_count == 0)
{
printf("You need digits\n");
}
if(punct_count == 0)
{
printf("You need a special character\n");
}
if(upper_count != 0 && digit_count != 0 && punct_count != 0 &&
length > 12)
{
printf("Your password is strong!\n");
}
if(upper_count != 0 && digit_count != 0 && punct_count != 0 &&
length <= 12)
{
printf("Your password is OK\n");
}
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 3 years ago.
Improve this question
I have an array formed from a text file imported by stdin.
The text file looks like this:
"Name"
"Number"
"Name"
"Number"
...
The entire code:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(int argc, char** argv)
{
//number of arguments
if (argc > 2)
{
fprintf(stderr, "Too many arguments\n");
return 1;
}
//check argument 1
{
if (argc == 2)
{
unsigned i = 0;
while (i < strlen(argv[1]))
{
if ((isdigit(argv[1][i])) == 0)
{
fprintf(stderr, "Enter a number\n");
return 1;
}
i++;
}
}
else
{
fprintf(stderr, "argument\n");
return -1;
}
}
//find \n and separate
int g = 0;
int c = 0;
char buffer[102];
char people[42][102];
char numbers[42][102];
while (fgets(buffer, sizeof buffer, stdin) != NULL)
{
if (g % 2 == 0)
{
strcpy(people[c], buffer);
//printf("%s", people[c]);
}
if (g % 2 == 1)
{
strcpy(numbers[c], buffer);
c++;
}
g++;
}
//convert and remove \n
char conv_people[42][102];
for (int i = 0; i < c; i++)
{
for (unsigned j = 0; j < strlen(people[i]); j++)
{
if (islower(people[i][j]) == 0 && people[i][j] != ' ' && people[i][j] != '.')
{
if (people[i][j] == '\n')
{
conv_people[i][j] = '\0';
}
people[i][j] = conv_people[i][j] + 32;
}
}
}
//covert to numbers
char conv[42][102];
for (int i = 0; i < c; i++)
{
for (unsigned j = 0; j < strlen(people[i]); j++)
{
if (conv_people[i][j] == ' ' || conv_people[i][i] == '.' || conv_people[i][i] == '\n' || conv_people[i][i] == '\0')
{
conv[i][j] = '0';
}
if (conv_people[i][j] == 'a' || conv_people[i][j] == 'b' || conv_people[i][j] == 'c')
{
conv[i][j] = '2';
}
if (conv_people[i][j] == 'd' || conv_people[i][j] == 'e' || conv_people[i][j] == 'f')
{
conv[i][j] = '3';
}
if (conv_people[i][j] == 'g' || conv_people[i][j] == 'h' || conv_people[i][j] == 'i')
{
conv[i][j] = '4';
}
if (conv_people[i][j] == 'j' || conv_people[i][j] == 'k' || conv_people[i][j] == 'l')
{
conv[i][j] = '5';
}
if (conv_people[i][j] == 'm' || conv_people[i][j] == 'n' || conv_people[i][j] == 'o')
{
conv[i][j] = '6';
}
if (conv_people[i][j] == 'p' || conv_people[i][j] == 'q' || conv_people[i][j] == 'r' || conv_people[i][j] == 's')
{
conv[i][j] = '7';
}
if (conv_people[i][j] == 't' || conv_people[i][j] == 'u' || conv_people[i][j] == 'v')
{
conv[i][j] = '8';
}
if (conv_people[i][j] == 'w' || conv_people[i][j] == 'x' || conv_people[i][j] == 'y' || conv_people[i][j] == 'z')
{
conv[i][j] = '9';
}
}
}
//compare
int i = 0;
while (i < c)
{
if (strstr(conv[i], argv[1]) != NULL)
printf("%s, %s", people[i], numbers[i]);
if (strstr(numbers[i], argv[1]) != NULL)
printf("%s, %s", people[i], numbers[i]);
i++;
}
return 0;
}
The program takes a list of people and their phone numbers and searches it using argv[1]
The output always omits the first capital letter in each word
So if the file contains a name like: Barrack Obama
the program returns arrack bama
The numbers and converted names are working fine
I didn't want to post the whole thing because it's extremely ugly.
I've run the code and John is output as Éohn. It likely comes from
people[i][j] = conv_people[i][j] + 32;
because you never set any values in conv_people[i] except a terminator.
If I add this first line in the loop
strcpy(conv_people[i], people[i]);
then is outputs
john
with a lower case initial letter.
Aside: it is safer and convenient to use
people[i][j] = tolower(conv_people[i][j]);
which doesn't even need to be tested to see if an uppercase letter was passed.
Im trying to write a function that scans in IP addresses on user input and has three main conditions:
If the IP address is valid, valid_addresses += 1
If the IP address is precisely -1.-1.-1.-1 then stop scanning for any further IP addresses and return valid_addresses (should contain the number of valid addresses).
If the IP address contains any value that is either below 0 or above 255, printf("Invalid input.\n") but continue scanning for further IP addresses (don't terminate the loop).
My current attempt is simply printing "Invalid input":
Main:
#include <stdio.h>
int LENGTH = 5; /* Tells the function how many IP addresses the user needs to provide on input */
char dot; /* Stores the points between digits */
struct ipaddr{ /* Making the ip address struct */
int octet1;
int octet2;
int octet3;
int octet4;
}; typedef struct ipaddr ipaddr_t;
int get_valid_ip_addrs(ipaddr_t addr_array[], int addr_array_len); /* Function prototype */
int main(){
struct ipaddr addr_array[LENGTH]; /* Variable declaration */
get_valid_ip_addrs(addr_array, LENGTH); /* Function call */
}
Function definition
int get_valid_ip_addrs(ipaddr_t addr_array[], int addr_array_len){
int valid_inputs = 0, i, k;
for(i = 0; i < addr_array_len; i++){
scanf("%i%c%i%c%i%c%i", &addr_array[i].octet1, &dot, &addr_array[i].octet2, &dot,
&addr_array[i].octet3, &dot, &addr_array[i].octet4);
/* Condition 1. (if the address is valid) */
for(k = 0; k < addr_array_len; k++){
if(addr_array[k].octet1 > 0 && addr_array[k].octet1 < 256 &&
addr_array[k].octet2 > 0 && addr_array[k].octet2 < 256 &&
addr_array[k].octet3 > 0 && addr_array[k].octet3 < 256 &&
addr_array[k].octet4 > 0 && addr_array[k].octet4 < 256){
valid_inputs = valid_inputs + 1;
}
/* Condition 2 (if the address is -1.-1.-1.-1) */
else if(addr_array[k].octet1 == -1 &&
addr_array[k].octet2 == -1 &&
addr_array[k].octet3 == -1 &&
addr_array[k].octet4 == -1){
return valid_inputs;
}
/* Condition 3 - if the address is invalid */
else if(addr_array[k].octet1 < 0 || addr_array[k].octet1 > 255 ||
addr_array[k].octet2 < 0 || addr_array[k].octet2 > 255 ||
addr_array[k].octet3 < 0 || addr_array[k].octet3 > 255 ||
addr_array[k].octet4 < 0 || addr_array[k].octet4 > 255){
printf("Invalid input.\n");
}
}
}
return valid_inputs;
}
I cant seem to figure out why my program doesn't do what i'm expecting it to do, any help for a beginner is greatly appreciated!
Try this :
typedef enum
{
IP_GET_OK,
IP_GET_ERROR,
IP_GET_END,
}IP_STATUS_t;
IP_STATUS_t getIP4(char *buff, int *ip4)
{
IP_STATUS_t result = IP_GET_ERROR;
if(buff && ip4 && fgets(buff, 32, stdin))
{
if(sscanf(buff, "%d.%d.%d.%d", &ip4[0], &ip4[1], &ip4[2], &ip4[3]) == 4)
{
int allminusone = 1;
for(size_t index = 0; index < 4; index++)
{
allminusone = allminusone && (ip4[index] == -1);
}
if(allminusone)
{
result = IP_GET_END;
}
else
{
result = IP_GET_OK;
for(size_t index = 0; index < 4; index++)
{
if(ip4[index] < 0 || ip4[index] > 0xff )
{
result = IP_GET_ERROR;
break;
}
}
}
}
}
return result;
}
You have an extra inner k loop. in which in the first case you only have one input but you still iterate over all the elements for which the behavior may be undefined.
int get_valid_ip_addrs(ipaddr_t addr_array[], int addr_array_len){
int valid_inputs = 0, i, k;
for(i = 0; i < addr_array_len; i++){
scanf("%d%c%d%c%d%c%d", &addr_array[i].octet1, &dot,
&addr_array[i].octet2, &dot,&addr_array[i].octet3, &dot, &addr_array[i].octet4);
/* Condition 1. (if the address is valid) */
if(addr_array[i].octet1 > 0 && addr_array[i].octet1 < 256 &&
addr_array[i].octet2 > 0 && addr_array[i].octet2 < 256 &&
addr_array[i].octet3 > 0 && addr_array[i].octet3 < 256 &&
addr_array[i].octet4 > 0 && addr_array[i].octet4 < 256){
valid_inputs = valid_inputs + 1;
}
/* Condition 2 (if the address is -1.-1.-1.-1) */
else if(addr_array[i].octet1 == -1 &&
addr_array[i].octet2 == -1 &&
addr_array[i].octet3 == -1 &&
addr_array[i].octet4 == -1){
return valid_inputs;
}
/* Condition 3 - if the address is invalid */
else if(addr_array[i].octet1 < 0 || addr_array[i].octet1 > 255 ||
addr_array[i].octet2 < 0 || addr_array[i].octet2 > 255 ||
addr_array[i].octet3 < 0 || addr_array[i].octet3 > 255 ||
addr_array[i].octet4 < 0 || addr_array[i].octet4 > 255){
printf("Invalid input.\n");
}
}
return valid_inputs;
}
The following program gives the result as 0 instead of the expected decimal equivalent of the hexadecimal string constant.
#include <stdio.h>
int my_htoi(char[]);
int main(void) {
printf("%d", my_htoi("0xABC"));
return 0;
}
int my_htoi(char str[]) {
int i, num = 0;
for (i = 0; i != '\0'; ++i) {
if (str[i+1] == 'x' || str[i+1] == 'X') {
i = i + 1;
continue;
}
if (str[i] >= '0' && str[i] <= '9') {
num = num * 16 + (str[i] - '0');
} else if (str[i] >= 'a' && str[i] <= 'f') {
num = num * 16 + (str[i] - 'a' + 10);
} else if (str[i] >= 'A' && str[i] <= 'F') {
num = num * 16 + (str[i] - 'A' + 10);
}
}
return num;
}
While the following program runs fine and outputs the correct decimal equivalent of the hexadecimal string constant.
#include <stdio.h>
#include <string.h>
int my_htoi(char[]);
int main(void) {
printf("%d", my_htoi("0xABC"));
return 0;
}
int my_htoi(char str[]) {
int i, num = 0;
for (i = 0; i < strlen(str); ++i) {
if (str[i+1] == 'x' || str[i+1] == 'X') {
i = i + 1;
continue;
}
if (str[i] >= '0' && str[i] <= '9') {
num = num * 16 + (str[i] - '0');
} else if (str[i] >= 'a' && str[i] <= 'f') {
num = num * 16 + (str[i] - 'a' + 10);
} else if (str[i] >= 'A' && str[i] <= 'F') {
num = num * 16 + (str[i] - 'A' + 10);
}
}
return num;
}
The only difference is in the way we find the qualifying condition for the loop. Why does it not work with the null byte checking?
Wrong code: i != '\0' checks if the index is 0.
for(i = 0; i != '\0'; ++i) {
Should be the below to check if the element str[i] is the null character.
for(i = 0; str[i] != '\0'; ++i) {
Other issues exists unneeded increment, int overflow (better to use unsigned here), wrong x detection - consider "0x0x0x1", leading - or +, char str[] --> const char str[], ...
There are some problems in your code:
the loop index i is compared to '\0' instead of str[i], causing immediate termination of the loop with a return value of 0.
the test for x is incorrect: it would cause "1x2" to convert to 2 instead of 1.
you accept letters beyond f and convert them to digits. The function should instead stop parsing at the first character that is not a hex digit.
Here is a corrected version:
#include <stdio.h>
int my_htoi(const char[]);
int main(void) {
printf("%d", my_htoi("0xABC"));
return 0;
}
int my_htoi(const char str[]) {
int i = 0, num = 0;
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X'))
i += 2;
for (; str[i] != '\0'; ++i) {
if (str[i] >= '0' && str[i] <= '9') {
num = num * 16 + (str[i] - '0');
} else if (str[i] >= 'a' && str[i] <= 'f') {
num = num * 16 + (str[i] - 'a' + 10);
} else if (str[i] >= 'A' && str[i] <= 'F') {
num = num * 16 + (str[i] - 'A' + 10);
} else {
break;
}
}
return num;
}
I am trying to find the most efficient way to find tags in a given char array. These "tags" are a sequence of chars located randomly within a char array.
Here is an example: given a char array: {'a','s','s','1','m','s','g','e','x','x','r','s','1',...}. the tag "ss1" indicates the beginning of a message which contains every char until a sequence of "exx" is found, which a tag for the end of the message, and it keeps searching the array for the next sequence of "s1". In this example, the message here is "msg".
my initial design was (pseudo code)
while(array[i] != '\0')
if(array[i] == 's' && array[i+1] == 's' && array[i+2] == '1' )
int j = i+3;
if(array[j] != '\0' && array[j] == 'e' && array[j+1] == 'x' && array[j+2] == 'x' )
i += 3;
else
print(array[j]);
else i++; //next char
may be a little flawed, but you get the idea. Is there a better way? i thought about strstr but since I'm dealing with a char array here and still looping even after deciphering a message, I thought it might be difficult to implement.
Try to maintain a state denoting how much of the tag start and end you have found. Something like this: (This code will work even if the message within the tag is of arbitrary length)
int state = 0;
int found = 0;
int i = 0,j;
int msgStartIndex;
int msgEndIndex;
while(array[i]){
if((array[i] == 's' && state == 0) || (array[i] == 's' && state == 1) || (array[i] == '1' && state == 2) ){
state++;
if(!found && state == 3){
msgStartIndex = i+1;
found = 1;
}
}
else if(!found && (array[i] = 's' && state == 2))
state = 2;
else if(!found)
state = 0;
if((array[i] == 'e' && state == 3) || (array[i] == 'x' && state == 2) || (array[i] == 'x' && state == 1) ){
state--;
if(found && state == 0){
found = 0;
msgEndIndex = i-3;
for(j=msgStartIndex; j < msgEndIndex+1; j++)
printf("%c",array[j]);
printf("\n");
}
}
else if(found && (array[i] == 'e') && (state == 2 || state == 1))
state = 2;
else if(found)
state = 3;
i++;
}
Updated answer for start tag st1 and end tag ex1
int state = 0;
int found = 0;
int i=0,j;
int msgStartIndex;
int msgEndIndex;
while(array[i]){
if((array[i] == 's' && state == 0) || (array[i] == 't' && state == 1) || (array[i] == '1' && state == 2) ){
state++;
if(!found && state == 3){
msgStartIndex = i+1;
found = 1;
}
}
else if(!found && (array[i] = 's' && (state == 1 || state == 2)))
state = 1;
else if(!found)
state = 0;
if((array[i] == 'e' && state == 3) || (array[i] == 'x' && state == 2) || (array[i] == '1' && state == 1) ){
state--;
if(found && state == 0){
found = 0;
msgEndIndex = i-3;
for(j=msgStartIndex; j < msgEndIndex+1; j++)
printf("%c",array[j]);
printf("\n");
}
}
else if(found && (array[i] == 'e') && (state == 2 || state == 1))
state = 2;
else if(found)
state = 3;
i++;