c - 要求用户在 C 中输入几个数字的正确方法是什么?
问题描述
我正在尝试制作一个关于核导弹发射的 C 程序。以下是我到目前为止的源代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int nukeLaunchCode = 618243;
int NLC_input;
char *address;
int main(void) {
address = malloc(sizeof(char) * 60);
printf("\033[0;34m[INFO] C.E.R.B.E.R.U.S Activating");
fflush(stdout);
for (int i = 0; i < 3; i++){
printf(".");
sleep(1);
}
fflush(stdout);
printf("\n");
printf("\033[0;32m[INFO] C.E.R.B.E.R.U.S Initialized. Enter destination for nuke in address form: ");
fgets(address, 60, stdin);
printf("\033[0;32m[INFO] Geo locating address via Advanced UAV");
fflush(stdout);
for (int i = 0; i < 6; i++) {
printf(".");
fflush(stdout);
sleep(1);
}
printf("\n");
fflush(stdout);
printf("\033[0;31m[WARNING] Target Acquired. Enter 6-digit Nuke Confirmation code to proceed: ");
fgets(&NLC_input, 7, stdin);
return 0;
}
问题是代码末尾的 fgets。我收到一条警告说:
Incompatible pointer types passing 'int *' to parameter of type 'char *'
我尝试使用带有"%d"
转换符号的 scanf ,然后我收到另一个警告说:
'scanf' used to convert a string to an integer value, but function will not
report conversion errors; consider using 'strtol' instead
有人可以告诉我我做错了什么吗?此外,我还包含了 fflush 函数,因为我想做一些很酷的事情。我想在打印一个句子后每秒打印一定数量的点来动画加载类的东西。出于某种原因,如果没有 fflush 函数,命令会乱序执行,并且不会打印点。但即使使用 fflush 函数,打印的第一行也不会打印 3 个点,直到打印下一行。我很确定这是 fflush 函数中的错位,但是有人可以帮我解决这个问题吗?谢谢!
解决方案
好吧,让我们做一些很酷的事情,让你理顺。首先,正确的原型fgets()
是:
char *fgets(char *s, int size, FILE *stream);
在您的代码中,您已经声明int NLC_input;
了 ,但随后尝试将 的地址NLC_input
用作 的第一个参数fgets()
。不允许。将结果的地址int
放入一个指针中 int
,该指针与需要的指针(例如)int*
不匹配。 char
char*
fgets()
此外,您不能将用户输入的字符转换为数字形式(如int
)fgets()
。您必须使用strtol()
或sscanf()
将数组中包含的数字转换为数字。(但使用fgets()
用户输入做得很好,比尝试直接阅读要好得多scanf()
)
让我们通过添加来快速概述您的代码:
#include <stdio.h>
#include <unistd.h>
#define MAXC 1024 /* if you need a constant, #define on (or more) */
#define ADRSZ 60
(stdlib.h
删除,因为不需要动态分配address
)
int main(void) {
char address[ADRSZ], tmp[MAXC]; /* avoid global variables */
int nukeLaunchCode = 618243, NLC_input;
(注意:如果您不打算更改nukeLaunchCode
,那#define nukeLaunchCode 618243
会很好 - 但请注意,宏通常在 C 中的 ALL-CAPS 中定义。另一种选择是const int nukeLaunchCode 618243;
)
您只需要fflush()
在您准备好输出时,将它包含在几个额外的时间里,它不会产生任何影响。反而:
printf ("\033[0;34m[INFO] C.E.R.B.E.R.U.S Activating");
for (int i = 0; i < 3; i++) {
putchar ('.'); /* don't use printf for single-char */
fflush(stdout); /* fflush only needed when output required */
sleep(1);
}
printf ("\n\033[0;32m[INFO] C.E.R.B.E.R.U.S Initialized. "
"Enter destination for nuke in address form: ");
(注:已'\n'
包含在第二个开头printf()
)
现在开始输入:
if (!fgets(address, 60, stdin)) { /* validate EVERY user input */
puts ("(user canceled input)");
return 0;
}
printf ("\033[0;32m[INFO] Geo locating address via Advanced UAV");
for (int i = 0; i < 6; i++) {
putchar ('.');
fflush(stdout);
sleep(1);
}
printf ("\n\033[0;31m[WARNING] Target Acquired. "
"Enter 6-digit Nuke Confirmation code to proceed: ");
(注意:EOF
用户可以通过按Ctrl + d, (或在 Windows 上)生成手册来取消输入,Ctrl + z这不是错误,因此您应该EOF
为用户处理这种情况)
只需使用 读取您将转换为值的输入NLC_input
到临时数组中fgets()
,例如
if (!fgets (tmp, sizeof tmp, stdin)) { /* fill temporary array */
puts ("(user canceled input)");
return 0;
}
if (sscanf (tmp, "%d", &NLC_input) != 1) { /* validate EVERY conversion */
fputs ("error: invalid integer input.\n", stderr);
return 1;
}
现在开始验证启动代码:
if (NLC_input != nukeLaunchCode) { /* validate launch code */
fputs ("error: Invalid Code, self-destruct sequence started ", stdout);
for (int i = 0; i < 6; i++) {
putchar ('.');
fflush(stdout);
sleep(1);
}
puts (" B O O M ! ! !");
return 1;
}
puts ("Launch Code Valid, continuing ...");
}
示例使用/输出
搏一搏:
$ ./bin/launchcode
[INFO] C.E.R.B.E.R.U.S Activating...
[INFO] C.E.R.B.E.R.U.S Initialized. Enter destination for nuke in address form: N34W67.123
[INFO] Geo locating address via Advanced UAV......
[WARNING] Target Acquired. Enter 6-digit Nuke Confirmation code to proceed: 618244
error: Invalid Code, self-destruct sequence started ...... B O O M ! ! !
如果您还有其他问题,请仔细查看并告诉我。
推荐阅读
- python - 如何将表单提交重定向到另一个视图
- c - 如何在没有字符串函数的情况下将新字符串分配给 char 数组
- python - 不可散列的类型:停用词的“列表”错误
- matlab - Matlab 中的 repmat 函数不能始终如一地工作?
- android - Fabric 导致 Android Pie 用户崩溃
- php - 请对我的计数功能提供一点帮助。尝试了有关此主题的答案,但没有成功
- r - 将分位数桶应用于行
- python - 如何获取某个 .py 文件中定义的所有函数?
- javascript - 从 Vuejs 数据表中删除行
- html - 如何在 TripAdvisor 中使用 Puppeteer.js (node.js) 获取动态 Html 标签的内部文本?