我正在寻找一种方法来取一个字符串并检查3种可能性。
“符号表示”基本上类似于从0元素开始的关联数组,并随着添加更多符号而扩展。例如,假设C具有关联数组(我希望)与此peusdocode:
symbol_array['q'] = 3;
symbol_array['five'] = 5;
symbol_array['negfive'] = -5;
symbol_array['random294'] = 28;
signed int i;
string = get_from_input();
if(!(i = convert_to_int(string))) {
if(!(i = translate_from_symbol(string))) {
printf("Invalid symbol or integer\n");
exit(1);
}
}
printf("Your number: %d\n, i);
这个想法是,如果他们输入“5”,它会通过convert_to_int将其转换为5,如果他们输入“5”,它将通过translate_from_symbol将其转换为5。我认为可能最难的是如果他们输入“random294”它不会将其转换为294,而是转换为28.如果他们输入“foo”那么它将退出(1)。
我的一般问题是:(而不是发多个帖子)
制作convert_to_int
时,我知道我不应该使用atoi
,因为它不会失败。有人说要使用strtol
,但将它转换回非long int似乎很乏味。我发现的简单(读取:最短)方式是使用sscanf
:
int i;
if ((sscanf(string, "%d", &i)) == 1){
return i;
}
然而,有些人甚至瞧不起。如果不是sscanf或转换strtol,有什么更好的方法?
其次,我怎么能不仅返回一个整数,还知道它是否找到了整数。例如,如果用户输入“0”,那么它将返回0,从而在我的if语句中设置我的FALSE。我曾经考虑过使用-1,如果没有找到,但由于我正在返回signed int,那么这也会遇到同样的问题。在PHP中,我知道strpos
使用=== FALSE
最后,是否存在模拟关联数组和/或允许我在运行时将元素推送到数组的短代码?
答案 0 :(得分:1)
首先,您可能需要修改语法并将关键字与操作数区分开来,即"neg five"
而不是"negfive"
。否则,您对关键字的符号查找必须考虑每个前缀。如果您的关键字不允许包含数字,则"random294"
可能没问题。)
当然,sscanf
告诉您是否在返回值中找到了小数,并将该小数写入单独的int
,这很不错,但您必须注意尾随字符检查读取的字符数是否等于%n
格式的字符串长度。否则,sscanf
会将5x
视为合法的十进制数。 strtol
也会在解析后的十进制数字后面返回一个指向该位置的指针,但它依赖于我的口味检查err
。
strtol
使用长整数的事实应该不是问题。如果输入不适合int,请返回INT_MAX
或INT_MIN
或发出错误。
您还可以轻松地围绕sscanf
或strtol
编写适合您需求的包装函数。 (我知道我想要一个成功返回true的函数,并通过指针参数sscanf
样式存储整数,其中成功意味着:没有尾随的非数字字符。)
最后,关于关联数组:没有短代码,至少不在C中。您必须实现自己的哈希映射或使用库。作为初稿,我将使用线性字符串列表并逐一检查。这是一种非常天真的方法,但易于实现。我假设你没有从很多符号开始,而且你没有做很多检查,所以速度不应该是一个问题。 (您可以对数组进行排序并使用二进制搜索来加快速度,但每次插入后都必须重新排序。)一旦您的程序逻辑正常工作,您就可以开始考虑哈希映射。
答案 1 :(得分:0)
这样的事情可以帮到你的工作:
#include <stdio.h>
#include <string.h>
struct StringToLongLookUp {
char *str;
char *num;
};
struct StringToLongLookUp table[] =
{
{ "q" , "3" },
{ "five" , "5" },
{ "negfive" , "-5" },
{ "random294", "28" }
};
int translate_from_symbol(char **str)
{
int i;
for(i = 0; i < (sizeof(table) / sizeof(struct StringToLongLookUp)); i++)
{
if(strcmp(*str, table[i].str) == 0)
{
*str = table[i].num;
return 1; // TRUE
}
}
return 0; // FALSE
}
int main()
{
char buf[100];
char *in = buf;
char *out;
int val;
scanf("%s", in);
translate_from_symbol(&in);
val = strtol(in, &out, 10);
if (in != out)
{
printf("\nValue = %d\n", val);
}
else
{
printf("\nValue Invalid\n");
}
}
当然,你得到的很长,但转换为int应该不是上面提到的问题。