C语言 如果字符串长度大于给定参数 if 语句,则不激活 else 部分



具有输入验证的基本加密,如果输入在定义的参数内,则需要用户输入通过每个阶段,则程序根据需要工作,如果输入大于定义的参数,否则应触发说密码无效,而是在没有用户输入的情况下运行整个程序以触发前进。


#include <stdio.h> //library containing built in functions for C
#include <stdlib.h> // contains general purpose library for C
#include <string.h>  //library containing methods for manipulating strings
int main()
{
// creates character input array of size 5
char input[20];
//initialize variable i
int i;
//initialize variable length
int length;
//prints the phrase
//printf("Your pass phrase is: ");
// used to read input string, gets replaced with fgets to secure input to array length
//fgets(input,11,stdin);
//assigns input to array length
//length = strlen(input);
//prints the phrase
printf("Your pass phrase is: ");
fgets(input,11,stdin);
//assigns input to array length
length = strlen(input);
// if loop that if entered text is longer than 0 but shorter than 6 will encrypt data
if ((length > 0 && length <=10)){
// encrypts array iteratting through elements
for (i=0; i<length; i++)
// uses bitwise xor cipher to encrypt using 0x7f which shifts the characters out of the standard ascii range
input[i] = 0x7F ^ input[i];
// prints the encrypted text in an unreadable format
puts("To see the encrypted text press enter: ");
getchar();
// iterates through the area printing the encrypted characters.
for(i=0;i<length; i++)
putchar(input[i]);
// uses xor cipher to shift data back into array by undoing the shift caused by 0x7f
for(i=0; i<length; i++)
input[i] = 0x7F ^ input[i];
// prints the now readable array
puts("nTo see recovered text press enter:");
getchar();
//iterates through the array printing the contained characters
for(i=0; i<length; i++)
putchar(input[i]);
}
// prints the following phrase if the array is empty.
else{
puts("User input has been checked and a valid pass phrase was not entered.");
}
return 0;
}

我试图破译你用代码的目的是什么,我已经阅读了茶叶并得出结论(也许是错误的),即你问题的关键是针对加密本身的输入和分支控制。

">

孔子"评论只是半心半意的建议,因为"永不吝啬缓冲区大小">是您通过提示用户指示来控制采用哪些分支的能力的核心。为什么?

  • 如果像在原始代码中一样,缓冲区大小为20,并告诉fgets最多读取10个字符,那么如果用户输入的字符超过10个字符,则其余字符将保留stdin未读取状态。
  • 任何留在stdin未读的字符都将愉快地用作后面每个getchar()语句的输入,从而导致您完全失去对代码分支方式的控制。
  • 使用足够大小的缓冲区并允许fgets一次使用一整行将确保stdin(输入缓冲区)中没有未读字符。您会发现这是在 C 中获取大多数用户输入的关键。

因此,确保您拥有足够大小的缓冲区并在每次使用一行输入,这对于能够控制代码的下一步位置至关重要。

提供能够容纳每行输入的缓冲区的替代方法是读取所需的字符数,然后在下一个输入之前手动清空stdin。这就像读取字符一样简单,直到达到'n'EOF。但。。。有一个问题。在尝试使用任何功能清空stdin之前,您必须知道字符仍然存在(例如getchar()将阻止 - 等待输入,直到输入存在才能被读取)。如果在没有任何要清空的内容时尝试以这种方式清空stdin,则用户将盯着闪烁的光标,想知道该怎么做。

回到你的代码。逻辑有点难以理解,但从包含的注释来看,您似乎考虑了一个正确的密码短语来加密它,一个包含1-5字符的短语。空密码或包含 6 个或更多字符的密码短语被视为无效。(从传递阶段的角度来看,实际数字是多少并不重要 - 这是一个关于输入和分支控制的练习)

如果我理解1-5字符(加密)或06或更多(无效)逻辑,那么您将需要调整代码的结构以更接近这一点。 从概述的角度来看,您要么有一个很好的密码短语来加密,要么没有。这将控制代码中的主要分支。您可以在单个if {..} else {..}语句中提供逻辑,例如

/* if input is longer than 0 but shorter than 6, encrypt data */
if (length && length < 6) {
/* all your good pass phrase code goes here */
}
else {  /* invalid pass phrase to begin with */
fputs ("error: pass phrase empty or greater than 5 chars.n", stderr);
return 1;
}

将上面的内容与示例中的多个独立语句组进行对比,应该可以理解为什么您在代码中的决策树中遇到问题。

现在转到提示用户按Enter键。当您尝试使用单个getchar()捕获该输入时,它非常脆弱,如果stdin中存在任何字符,则可能会被跳过,并且如果按下超过Enter,则具有相同的问题,即stdin字符处于未读状态。在这里,只需声明另一个字符数组以用于临时输入,其大小与input[]数组相同。现在,与其getchar(),不如再次使用fgets(),甚至单独捕获Enter

(它非常有能力做到这一点,因为它读取并将'n'包含在它填充的缓冲区中,它不会像getchar()那样阻止等待输入)

担心在两个缓冲区中使用 512 字节的大小 - 不要。大多数操作系统提供至少 1 Meg 的堆栈空间,因此 512 字节仅代表可用堆栈存储的0.048%。(您仍然有1048576 - 512 = 1048064字节的堆栈空间可用)

通过该更改,可以重写您的代码以包含与在第一个if {...}块中处理良好/加密密码相关的所有逻辑,例如

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXC 256    /* if you need a constant, #define one (or more) */
int main (void) {
char    input[MAXC],    /* buffer to hold pass phrase */
tmp[MAXC];      /* temporary buffer for [enter] input */
size_t  i,              /* declares an UNINTIALIZED size_t */
length;         /*           (ditto)              */
fputs ("Your pass phrase is: ", stdout); /* no conversion, fputs is fine */
if (!fgets (input, MAXC, stdin)) {
fputs ("(user canceled input)n", stderr);
return 1;
}
/* remove 'n' by overwriting with '' (if present)
* saving length of input in length
*/
input[(length = strcspn(input, "n"))] = 0;
/* if input is longer than 0 but shorter than 6, encrypt data */
if (length && length < 6) {
int     encrypted = 0;  /* flag keeping state of if pw encrypted */
for (i = 0; i < length; i++)    /* encrypt the pass phrase */
input[i] ^= 0x7f;
encrypted = 1;                  /* set flag true */
/* print encrypted text in an hex format (change as desired) */
fputs ("nTo see the encrypted text press [enter]: ", stdout);
if (fgets (tmp, MAXC, stdin) && *tmp == 'n') {
for (i = 0; i < length; i++)
printf (" %02x", input[i]);
putchar ('n');
}
/* decrypt restoring plain-text pass phrase */
fputs ("ndecrypted pass phrase, press [enter]: ", stdout);
if (fgets (tmp, MAXC, stdin) && *tmp == 'n') {
for (i = 0; i < length; i++)
input[i] ^= 0x7f;
encrypted = 0;              /* set flag false after decryption */
}
else {  /* if user pressed any other key (or generated EOF) */
fputs ("error: user chose not to decrypt pass phrase.n", stderr);
return 1;
}
/* output decrypted plain-text pass pharase (if decrypted) */
fputs ("nTo see recovered text press [enter]: ", stdout);
if (fgets (tmp, MAXC, stdin) && *tmp == 'n' && !encrypted) {
for (i = 0; i < length; i++)
putchar (input[i]);
putchar ('n');
}
}
else {  /* invalid pass phrase to begin with */
fputs ("error: pass phrase empty or greater than 5 chars.n", stderr);
return 1;
}
return 0;
}

(注意:encrypted标志上方仅用于保存input[]的内容当前是否已加密的状态,以便在您尝试打印解密的密码短语之前提供额外的条件检查)

示例使用/输出

有效密码大小写:

$ ./bin/pass0-5
Your pass phrase is: abcde
To see the encrypted text press [enter]:
1e 1d 1c 1b 1a
decrypted pass phrase, press [enter]:
To see recovered text press [enter]:
abcde

用户选择不解密大小写:

$ ./bin/pass0-5
Your pass phrase is: abcde
To see the encrypted text press [enter]:
1e 1d 1c 1b 1a
decrypted pass phrase, press [enter]: No, I don't want to!
error: user chose not to decrypt pass phrase.

密码短语太长的大小写:

$ ./bin/pass0-5
Your pass phrase is: abcdef
error: pass phrase empty or greater than 5 chars.

密码空大小写:

$ ./bin/pass0-5
Your pass phrase is:
error: pass phrase empty or greater than 5 chars.

我不知道我是否正确阅读了茶叶,但从您的评论和原始问题来看,这个领域实际上是您的重点。仔细看看,如果你还有其他问题,让我知道,如果我弄错了你问题的主要要点,让我知道,我很乐意进一步提供帮助。

最新更新