字符串可以用作C?
中的数组索引例: 字符串对应的值 “ONE”1 “两个”2 “五”5 “十”10
当上面列表中的字符串传递给函数时,该函数必须返回上面指示的相应值。可以通过将字符串声明为索引
来声明一个常量数组来实现int *x;
x["ONE"] = 1;
x["TWO"] = 2;
x["FIVE"] = 5;
x["TEN"] = 5;
return x["string received by the function"];
上述逻辑无法按预期工作;是否有一种解决方法来实现上述逻辑,以便有一个字符串索引数组?
答案 0 :(得分:17)
它可能会编译,但它不起作用。
目前还不完全清楚你要实现的目标。我想你想要associative array,在这种情况下你应该找到一个库实现。
如果您正在寻找更像enumerated type的内容,并且可以依赖C89,请查看以下内容:
enum cardsuit {
CLUBS,
DIAMONDS,
HEARTS,
SPADES
};
如果您不能依赖C89,那么您应该尝试一些typedef
技巧。
答案 1 :(得分:10)
对于你应该做的事情还有其他很好的答案,所以我想我会解释你在做什么以及为什么它在编译而不起作用。
在C中,通过使用数组或指针以及某种整数来完成数组引用。 (在x [1]中,x是数组,1是整数)。只要您使用某种整体类型,它就会按预期工作。
假设你有一些不是整数的东西。在这种情况下,C实现将查看它是否可以将其转换为适当的类型,因此您最终得到数组和整数。这样的情况会让你遇到麻烦(在C ++中稍微复杂一点的版本会让经验丰富的人感到困惑)。
在C中,像“one”这样的文字字符串是const char *类型,意味着指向您无法更改的字符。实际值是字符串实际驻留在内存中的内存地址。通常情况下,你不会注意这个指针值,看看字符串值,但这里有一个问题。
在C中,任何数据指针都可以转换为某种整数,并且会自动转换。因此,你有一个像“one”这样的字符串,它的值是代表内存地址的任何数字。在C期望某种整数的情况下使用它,它将被转换为某个整数值或其他。
因此,这就是x [“ONE”]正在发生的事情。 C系统必须将字符串“ONE”放在内存中的哪个位置,并不重要。它很可能是一个内存相当大的地方,很可能是数十亿。当它看到x [“ONE”]时,它会尝试将该值转换为整数,并将其用作下标。因此,您尝试远远超出其范围访问数组x,这导致了问题。要么你正在尝试使用你不允许使用的内存,而系统只是阻止你,或者你正在捣乱你应该独自留下的一大块内存,而且它可能会以某种神秘的方式失败。 / p>
答案 2 :(得分:3)
您需要编写一个将字符串映射到整数的函数,或者使用整个枚举(然后可能是将枚举值映射到字符串的函数)。
通常,后者更好:传递整数,因此实现不依赖于可能在表示中使用的字符串的细节。例如,考虑如何管理本地化(翻译),如果你需要让那些用不同语言的人认为这些字符串是可口的。
答案 3 :(得分:3)
您可以使用bsearch()
提供的函数stdlib.h
轻松构建查找表。一个工作的例子就是这样:
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#define count(ARRAY) (sizeof(ARRAY)/sizeof(*ARRAY))
struct item
{
const char * name;
int value;
};
static _Bool sorted;
static struct item items[] =
{
{ "one", 1 },
{ "two", 2 },
{ "three", 3 },
{ "ten", 10 }
};
static int compare(const void * p1, const void * p2)
{
return strcmp(*((const char **)p1), *((const char **)p2));
}
int get(const char * name)
{
if(!sorted)
{
qsort(items, count(items), sizeof(*items), compare);
sorted = 1;
}
struct item * item = bsearch(&name, items, count(items), sizeof(*items),
compare);
return item ? item->value : 0;
}
int main(int argc, char ** argv)
{
int i;
for(i = 1; i < argc; ++i)
printf("%i\n", get(argv[i]));
return 0;
}
答案 4 :(得分:1)
你正在寻找的东西可能相当于一个关联数组,在C语言中不能提供相同的语法糖,但是没有一些愚蠢的结果。
但是,如果您的数据符合密钥,则可以提供的是散列图 - &gt;价值对。您需要的是适当的哈希函数。
这里有一个很好的简单哈希表示例:
答案 5 :(得分:0)
如前所述,您需要一个关联数组或哈希映射或等价物。这种代码的一个可能来源是Hanson的“C Interfaces and Implementations”(Google Code处的代码 - 在使用之前仔细检查许可条款等。)
答案 6 :(得分:0)
这是一个旧线程,但我认为这对于那些寻找实现的人来说可能仍然有用。它不需要太多代码; Hank Gay建议我没有任何额外的库,我做了大约100行。我把它称为字典,因为它与python数据类型相似(有点)。这是代码:
#include <stdlib.h>
#include <stdio.h>
#include <stdbool.h>
typedef struct hollow_list hollow_list;
struct hollow_list{
unsigned int size;
void *value;
bool *written;
hollow_list *children;
};
//Creates a hollow list and allocates all of the needed memory
hollow_list hollow_list_create(unsigned int size){
hollow_list output;
output = (hollow_list) {.size = size, .value = (void *) 0, .written = calloc(size, sizeof(bool)), .children = calloc(size, sizeof(hollow_list))};
return output;
}
//Frees all memory of associated with a hollow list and its children
void hollow_list_free(hollow_list *l, bool free_values){
int i;
for(i = 0; i < l->size; i++){
hollow_list_free(l->children + i, free_values);
}
if(free_values){
free(l->value);
}
free(l);
}
//Reads from the hollow list and returns a pointer to the item's data
void *hollow_list_read(hollow_list *l, unsigned int index){
if(index == 0){
return l->value;
}
unsigned int bit_checker;
bit_checker = 1<<(l->size - 1);
int i;
for(i = 0; i < l->size; i++){
if(bit_checker & index){
if(l->written[i] == true){
return hollow_list_read(l->children + i, bit_checker ^ index);
} else {
return (void *) 0;
}
}
bit_checker >>= 1;
}
}
//Writes to the hollow list, allocating memory only as it needs
void hollow_list_write(hollow_list *l, unsigned int index, void *value){
if(index == 0){
l->value = value;
} else {
unsigned int bit_checker;
bit_checker = 1<<(l->size - 1);
int i;
for(i = 0; i < l->size; i++){
if(bit_checker & index){
if(!l->written[i]){
l->children[i] = hollow_list_create(l->size - i - 1);
l->written[i] = true;
}
hollow_list_write(l->children + i, bit_checker ^ index, value);
break;
}
bit_checker >>= 1;
}
}
}
typedef struct dictionary dictionary;
struct dictionary{
void *value;
hollow_list *child;
};
dictionary dictionary_create(){
dictionary output;
output.child = malloc(sizeof(hollow_list));
*output.child = hollow_list_create(8);
output.value = (void *) 0;
return output;
}
void dictionary_write(dictionary *dict, char *index, unsigned int strlen, void *value){
void *hollow_list_value;
dictionary *new_dict;
int i;
for(i = 0; i < strlen; i++){
hollow_list_value = hollow_list_read(dict->child, (int) index[i]);
if(hollow_list_value == (void *) 0){
new_dict = malloc(sizeof(dictionary));
*new_dict = dictionary_create();
hollow_list_write(dict->child, (int) index[i], new_dict);
dict = new_dict;
} else {
dict = (dictionary *) hollow_list_value;
}
}
dict->value = value;
}
void *dictionary_read(dictionary *dict, char *index, unsigned int strlen){
void *hollow_list_value;
dictionary *new_dict;
int i;
for(i = 0; i < strlen; i++){
hollow_list_value = hollow_list_read(dict->child, (int) index[i]);
if(hollow_list_value == (void *) 0){
return hollow_list_value;
} else {
dict = (dictionary *) hollow_list_value;
}
}
return dict->value;
}
int main(){
char index0[] = "hello, this is a test";
char index1[] = "hello, this is also a test";
char index2[] = "hello world";
char index3[] = "hi there!";
char index4[] = "this is something";
char index5[] = "hi there";
int item0 = 0;
int item1 = 1;
int item2 = 2;
int item3 = 3;
int item4 = 4;
dictionary d;
d = dictionary_create();
dictionary_write(&d, index0, 21, &item0);
dictionary_write(&d, index1, 26, &item1);
dictionary_write(&d, index2, 11, &item2);
dictionary_write(&d, index3, 13, &item3);
dictionary_write(&d, index4, 17, &item4);
printf("%d\n", *((int *) dictionary_read(&d, index0, 21)));
printf("%d\n", *((int *) dictionary_read(&d, index1, 26)));
printf("%d\n", *((int *) dictionary_read(&d, index2, 11)));
printf("%d\n", *((int *) dictionary_read(&d, index3, 13)));
printf("%d\n", *((int *) dictionary_read(&d, index4, 17)));
printf("%d\n", ((int) dictionary_read(&d, index5, 8)));
}
不幸的是你无法复制list [x]语法,但这是我提出的最佳选择。
答案 7 :(得分:-2)
在“普通C”中,您可以模仿使用字符串作为索引,但不能以您想要的方式使用QUITE。但是,这样做很少有用,而且大多数都是使代码不可读的好方法。您似乎想要的是能够将字符串键用于字典(或“散列表”,如果您愿意)并且C中没有内置数据结构。确切的设计将取决于您的内容想要(事实上,如果这是家庭作业的一部分,你可能甚至不需要使用完整的哈希表实现,但可能会使用性能较低的静态编码)。
在a [b]构造的“索引位置”中使用字符串(OK,char数组)的示例:
int main (void)
{
char *str = "This is a test string";
int x;
for (x=0; x < 12; x += 3)
putchar(x[str]);
printf("\n");
return 0;
}
据我所知,上面是合法的C,具有明确定义的输出(字符串“Tss ssi”)。它依赖于a [b]被定义为与*(a + b)相同的事实。