尝试编写 fgets 函数的一个新版本 tfgets——tfgets 函数的输入与 fgets 函数一致。) 如果用户连续输错三次,则尝试使用非本地跳转,给出提示, 并不允许该用户再次尝试。
时间: 2023-08-22 11:25:20 浏览: 92
好的,这是一个有趣的编程问题。这里是一个可能的实现:
```
#include <setjmp.h>
#include <stdio.h>
#define MAX_TRIES 3
jmp_buf env;
int tries = 0;
char* tfgets(char* str, int n, FILE* stream) {
char* ret = fgets(str, n, stream);
if (ret == NULL) {
return ret;
}
if (strcmp(str, "secret") == 0) {
longjmp(env, 1);
}
return ret;
}
int main() {
char str[100];
if (setjmp(env) != 0) {
printf("You've been locked out\n");
return 1;
}
while (tries < MAX_TRIES) {
printf("Enter password: ");
if (tfgets(str, 100, stdin) == NULL) {
break;
}
if (strcmp(str, "password") == 0) {
printf("Access granted\n");
break;
}
tries++;
}
if (tries == MAX_TRIES) {
printf("Too many tries\n");
}
return 0;
}
```
在这个实现中,我们定义了一个 `tfgets` 函数,它与 `fgets` 函数具有相同的参数和返回值,但是如果用户输入了 "secret",则会立即跳转到 `env` 标记处。我们在 `main` 函数中使用了一个循环来尝试多次输入密码,如果尝试次数超过了 `MAX_TRIES`,则会给出警告并退出程序。在循环中,我们使用 `tfgets` 函数而不是 `fgets` 函数来获取用户输入。如果 `tfgets` 函数返回 `NULL`,则说明用户已经到达了文件末尾,循环也会退出。
这个实现使用了 `setjmp` 和 `longjmp` 函数来实现非本地跳转。`setjmp` 函数保存了当前程序状态并返回一个标记,`longjmp` 函数则可以使用该标记来恢复程序状态并跳转到指定位置。在这个实现中,我们在 `main` 函数的循环中使用了 `setjmp` 函数来保存程序状态,并在 `tfgets` 函数中使用了 `longjmp` 函数来跳转到 `env` 标记处。如果用户输入了 "secret",则会触发这个跳转。
阅读全文