【发布时间】:2021-11-18 03:34:51
【问题描述】:
我需要一个“通用”scanf 函数来验证输入,同时为指令和错误打印一条消息。Scan 是一个接受 void 指针的函数,它是将存储输入值、类型说明符和消息的变量。代码如下所示:
void scan(char specifier, void *dest, string instruction, string error) {
bool success = true;
do {
if(!success) {
while (getchar()!='\n');
perror(error);
}
puts(instruction);
switch (specifier)
{
case 'd':
success = scanf(" %d", (int *)dest);
break;
case 's’:
// In this particular program I need the strings to be 30 bytes with spaces.
success = scanf(“ %29[^\n]s", (char *)dest);
break;
case 'h':
success = scanf(" %hd", (short *)dest);
break;
case 'f':
success = scanf(" %f", (float *)dest);
break;
}
} while (!success ); }
但是是否可以只将 void 指针转换为给定大小类型的指针而不是 switch?像这样:
double myVar;
size_t varSize = sizeof(double); void * dest = &myVar;
// specifierForDest is a string
scanf(specifierForDest, (varSize *)dest);
这样dest 就变成了一个指向大小为varSize 的变量的指针。
或者任何其他已知方法比为 C 中的每种类型编写 case 更好?
【问题讨论】:
-
你问错问题了。您正在尝试创建一些通用的扫描函数,并决定这样做的方法是将指针传递给
scanf,并将这些指针转换为“指向特定大小类型的指针”。但这不是一个正确的解决方案,因为scanf被指定为采用指向某些类型的指针,与转换规范相匹配,而不仅仅是指向特定大小的类型的指针。您的文字问题的答案是肯定的,我们可以使用(char (*)[n]) pointer轻松地将指针转换为指向 n 字节对象的指针。但这不是实现目标的正确方法。 -
我建议你放弃
scanf()并且:(1) 使用fgets()来读取用户输入和(2) 使用sscanf()来解析它。 -
这是 X-Y 问题。 \
-
不,@0__________,CS50 是用 C 编译器编译的。但它提供了一个库和头文件,该类的分配可以/应该使用,头文件定义的其中一件事是 typedef
string别名char *。这是 CS50 不喜欢的地方之一。 -
" %30[^\n]s"与char string[30]一起使用是错误的。应该是" %29[^\n]"。
标签: c void-pointers