我有以下方法来生成一个必须满足要求的字符串,但如果不满足验证要求,我需要某种子句循环回用户输入。我知道在Java中有后续读取但是我'我不确定C中所需的代码是什么,如果有人能发现错误,我也不认为我的其他语法是正确的语法。一些提示或建议会有所帮助, 感谢。
void validatePass()
{
FILE *fptr;
char password[MAX+1];
int iChar,iUpper,iLower,iSymbol,iNumber,iTotal,iResult,iCount;
//shows user password guidelines
printf("\n\n\t\tPassword rules: ");
printf("\n\n\t\t 1. Passwords must be at least 9 characters long and less than 15 characters. ");
printf("\n\n\t\t 2. Passwords must have at least 2 numbers in them.");
printf("\n\n\t\t 3. Passwords must have at least 2 uppercase letters and 2 lowercase letters in them.");
printf("\n\n\t\t 4. Passwords must have at least 1 symbol in them (eg ?, $, £, %).");
printf("\n\n\t\t 5. Passwords may not have small, common words in them eg hat, pow or ate.");
//gets user password input
printf("\n\n\t\tEnter your password following password rules: ");
scanf("%s", &password);
iChar = countLetters(password,&iUpper,&iLower,&iSymbol,&iNumber,&iTotal);
if(iUpper < 2)
{
printf("Not enough uppercase letters!!!\n");
}
else if(iLower < 2)
{
printf("Not enough lowercase letters!!!\n");
}
else if(iSymbol < 1)
{
printf("Not enough symbols!!!\n");
}
else if(iNumber < 2)
{
printf("Not enough numbers!!!\n");
}
else if(iTotal < 9 && iTotal > 15)
{
printf("Not enough characters!!!\n");
}
iResult = checkWordInFile("dictionary.txt",password);
if( iResult == gC_FOUND )
{
printf("\nFound your word in the dictionary");
}
else if
{
printf("\nCould not find your word in the dictionary");
}
iResult = checkWordInFile("passHistory.txt",password);
else if( iResult == gC_FOUND )
{
printf("\nPassword used");
}
else if
{
printf("\nOk to use!");
}
else
{
printf("\n\n\n Your new password is verified ");
printf(password);
}
//writing password to passHistroy file.
fptr = fopen("passHistory.txt", "w"); // create or open the file
for( iCount = 0; iCount < 8; iCount++)
{
fprintf(fptr, "%s\n", password[iCount]);
}
fclose(fptr);
printf("\n\n\n");
system("pause");
}//end validatePass method
答案 0 :(得分:1)
使用转到。这是少数需要保证的案例之一。
这是一个例子。正如您所看到的,它比while(0)
更清晰,并且会使编译器对-Wall
的抱怨更少!
// Returns whether or not the condition failed, printing the
// given error if it did.
static bool verifyThat(bool condition, const char* error) {
if(!condition) printf("%s", error);
return !condition;
}
void validatePass()
{
FILE *fptr;
char password[MAX+1];
int iChar,iUpper,iLower,iSymbol,iNumber,iTotal,iResult,iCount;
//shows user password guidelines
printf("\n\n\t\tPassword rules: ");
printf("\n\n\t\t 1. Passwords must be at least 9 characters long and less than 15 characters. ");
printf("\n\n\t\t 2. Passwords must have at least 2 numbers in them.");
printf("\n\n\t\t 3. Passwords must have at least 2 uppercase letters and 2 lowercase letters in them.");
printf("\n\n\t\t 4. Passwords must have at least 1 symbol in them (eg ?, $, £, %).");
printf("\n\n\t\t 5. Passwords may not have small, common words in them eg hat, pow or ate.");
get_user_password:
printf("\n\n\t\tEnter your password following password rules: ");
scanf("%s", &password);
iChar = countLetters(password,&iUpper,&iLower,&iSymbol,&iNumber,&iTotal);
iUpper = ...
iLower = ...
iSymbol = ...
iNumber = ...
iTotal = ...
if(verifyThat(iUpper >= 2, "Not enough uppercase letters!!!\n")
|| verifyThat(iLower >= 2, "Not enough lowercase letters!!!\n")
|| verifyThat(iSymbol >= 1, "Not enough symbols!!!\n")
|| verifyThat(iNumber >= 2, "Not enough numbers!!!\n")
|| verifyThat(iTotal >= 9, "Not enough characters!!!\n")
|| verifyThat(iTotal <= 15, "Too many characters!!!\n"))
goto get_user_password;
iResult = checkWordInFile("dictionary.txt", password);
if(verifyThat(iResult != gC_FOUND, "Password used."))
goto get_user_password;
printf("Your new password is verified.");
}
答案 1 :(得分:0)
看起来像做{...} while(...)循环的情况。 您正在寻找的“其他”就在字典查找之后。
编辑: 它会像这样工作:
do {
/* read password here */
...
if (condition not met) {
printf("condition not met!\n");
continue;
}
if (another condition not met) {
printf("another condition not met!\n");
continue;
}
...
} while(0);
EDIT2: 在另一个函数中进行测试可能是个好主意:
bool password_is_safe(char *password)
{
...
if (condition not met) {
printf("condition not met!\n");
return false;
}
if (another condition not met) {
printf("another condition not met!\n");
return false;
}
...
return true;
}
/* in another function */
...
do {
...
/* read password here */
...
} while(!password_is_safe(password));
这使得在不向上和向下滚动的情况下更容易理解程序的逻辑。
EDIT3:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define STRINGIFY(x) #x
#define STRINGIFY_VALUE(x) STRINGIFY(x)
#define MAX 80
static bool test_and_complain(const bool test, const char *complain)
{
if (test) {
printf("%s\n", complain);
}
return test;
}
static void write_history(const char *password)
{
FILE *f = fopen("passHistory.txt", "w");
// always check if fopen() was successful
if (!f) {
fprintf(stderr, "can't write password history\n");
exit(EXIT_FAILURE);
}
fprintf(f, "%s\n", password);
fclose(f);
}
void validatePass()
{
char password[MAX+1];
int iUpper,iLower,iSymbol,iNumber,iTotal;
//shows user password guidelines
printf("\n\n\t\tPassword rules: ");
printf("1. Passwords must be at least 9 characters long and less than 15 characters.");
printf("2. Passwords must have at least 2 numbers in them.");
printf("3. Passwords must have at least 2 uppercase letters and 2 lowercase letters in them.");
printf("4. Passwords must have at least 1 symbol in them (eg ?, $, £, %%).");
printf("5. Passwords may not have small, common words in them eg hat, pow or ate.");
// loop until we got a good password
bool pw_invalid;
do {
//gets user password input
printf("Enter your password following password rules: ");
// Security risc:
// Never ever use "%s" without specifying a length!
// scanf("%s", password);
scanf("%" STRINGIFY_VALUE(MAX) "s", password);
countLetters(password,&iUpper,&iLower,&iSymbol,&iNumber,&iTotal);
// Notice that you could eliminate the boolean variable and
// wrap all the tests in a single expression and put
// that inside the loop condition of the loop.
// I think it looks nicer this way though.
// Notice that the || operator does not evaluate the right hand
// expression if the left hand expression evaluates to true.
// I.e. after the first test fails, no other tests are performed.
// This is equivalent to the if-else cascade from before.
pw_invalid = false;
pw_invalid = pw_invalid || test_and_complain(
(iUpper < 2),
"Not enough uppercase letters!!!");
pw_invalid = pw_invalid || test_and_complain(
(iLower < 2),
"Not enough lowercase letters!!!");
pw_invalid = pw_invalid || test_and_complain(
(iSymbol < 1),
"Not enough symbols!!!");
pw_invalid = pw_invalid || test_and_complain(
(iNumber < 2),
"Not enough numbers!!!") ;
pw_invalid = pw_invalid || test_and_complain(
(iTotal < 9),
"Not enough characters!!!");
pw_invalid = pw_invalid || test_and_complain(
(checkWordInFile("dictionary.txt",password)==gC_FOUND),
"Found your word in the dictionary");
pw_invalid = pw_invalid || test_and_complain(
(checkWordInFile("passHistory.txt",password)==gC_FOUND),
"You already used this password recently");
} while(pw_invalid);
printf("\nYour new password is verified\n");
// Security risc:
// Never ever use a user supplied string as a format string!
// printf(password);
printf("%s\n", password);
//writing password to passHistroy file.
write_history(password);
printf("\n\n\n");
system("pause");
} //end validatePass method
如果这是作业,请回复您的成绩。 ; - )