2009-11-04 73 views
1

对不起,甚至不知道该怎么称呼这个,但是在这里。这是铸造?

假设我有:

char Fred[] = "1234 Evergreen Terrace"; 
char Pete[] = "4567 State Street"; 
char Mark[] = "123 North Street"; 

char Name[32]; 
gets(Name); 

,而不是写:

if(strcmp(name,"Fred")==0); 
    printf("You live at %s\n",Fred); 
else if(strcmp(name,"Pete")==0); 
    printf("You live at %s\n",Pete); 
else if(strcmp(name,"Mark")==0); 
    printf("You live at %s\n",Mark); 

是不是有办法通过书面跳过所有strcmps():

printf("You live at %s\n",<SOMETHING_HERE>Name) 

我需求更复杂,但上面的简单例子应该让我去。自从我了解了它已有近15年了,但我无法回想起来。 在此先感谢! Dan

+4

**从来没有**使用“获得”。由于它不允许你传递缓冲区的大小,所以“获取”不可能以安全的方式实现。函数“gets”是一种可以让您的应用程序出现缓冲区溢出漏洞的可靠方法,因此请保持清楚。 – 2009-11-04 15:37:46

+0

您的代码看起来像C,但标记为C++。您是否在寻找C或C++解决方案? – jalf 2009-11-04 16:18:35

回答

11
  • 使用字符串 - >字符串的std :: map。
  • 一个字符串从输入
  • 如果是在地图,打印

样品:

#include <map> 
#include <string> 
#include <iostream> 

int main() 
{ 
    typedef std::map< std::string, std::string > MapType; 
    MapType names; 

    names.insert(std::make_pair("Fred", "1234 Evergreen Terrace")); 
    names.insert(std::make_pair("Pete", "4567 State Street")); 
    names.insert(std::make_pair("Mark", "123 North Street")); 

    std::string input; 
    std::cin >> input; 
    MapType::iterator it = names.find(input); 
    if(it != names.end()) 
     std::cout << input << "lives at: " << it->second << std::endl; 

    return 0; 
} 
+0

为什么不使用地图[]来插入它看起来更直观的值:names [“Fred”] =“1234 Evergreen Terrace” – 2009-11-04 16:21:51

+0

因为使用insert而不是[]运算符向地图添加元素效率更高。它保存三个函数调用:创建临时字符串对象,赋值运算符调用和对临时字符串对象的析构函数调用。 – navigator 2009-11-04 18:49:29

3

maps in the STL

using namespace std; 
map<string, string> lookup(map<string,string>); 
lookup["Fred"] = string("1234 Evergreen Terrace"); 
... 
string name("Fred"); // or other values 

cout << "You live at " << lookup[name]; 
//Alternative using find to deal with missing name 

map<string,string>::iterator address(lookup.find(name)); //Edited to use find 
if (address != map.end()) { 
    cout << "You live at " << lookup[name]; 
} 
+2

确保你添加了一些东西来处理名称不在地图中的情况 – 2009-11-04 14:41:07

+1

与Mark相反,不要使用namespace std;而是使用std :: map,std ::字符串,std :: cout;'...导入当前名称空间中的所有名称空间符号实际上并不是必需的。 – 2009-11-04 14:42:06

+2

正如David Oneill暗示的那样,使用std :: map的find()方法通常更好。否则,你最终会添加你不知道的名字。 – 2009-11-04 14:46:12

2

你需要的是一个地图。将映射您的名字 - >地址的数据结构。

试着做这样的结构:

struct person { 
    char name[32]; 
    char address[256]; 
} 

然后创建人结构的数组:

struct person[] = { 
    {"fred", "1234 Evergreen Terrace"}, 
    {"pete", "4567 State Street"}, 
    {"mark", "123 North Street"} 
}; 

int numberOfPeople = 3; 

然后,当你需要找到一个可以搜索这样说:

for(int index = 0; index < numberOfPeople; index++) { 
    if(!strcmp(person[index].name, name)) { 
     printf("You live at %s.\n"); 
    } 
} 

显然有很多更高级的方法来做到这一点。我建议阅读课程和hashmaps。一个类是一个更高级的结构版本,可以让你做各种各样的整洁的东西。散列图是一种数据结构,它使用称为散列函数的功能将字符串用作查找正确地址的关键字。

或者,而不是学习的地图究竟是如何工作的,使你自己的,你总是可以偷懒,只是使用std ::地图)

2

您可以将姓名和地址以相关联的容器中,如存储STL映射的名称是关键字,地址是值。

std::map<std::string, std::string> people; 

// ... Add the entries to the map here ... 
people["Fred"] = "1234 Evergreen Terrace"; 
people["Pete"] = "4567 State Street"; 
people["Mark"] = "123 North Street"; 

那么单一的printf:

std::map<std::string, std::string>::const_iterator iter = people.find(Name); 
if(iter != people.end()) 
    printf("You live at %s\n", iter->second); 

请注意,您需要检查其中名称不存在地图内的情况下 - 例如使用find()如上所示。

+0

这也使用未经检查的输入在地图中查找。 – sbi 2009-11-04 14:50:46

+0

sbi - 正在捕获通过文本,但通过将检查添加到代码使其更加明确。 – 2009-11-04 14:57:38

+0

@Stephen:对不起,我错过了这段文字。但我认为现在这样比较好。但是,请注意,现在您正在执行_two_查找,而不是一个。尽管如此,我还是删除了我的倒票。 – sbi 2009-11-04 15:17:29

1

难道没有办法跳过所有的strcmp()吗?

在C++中,这是拼写std::map

std::map<string, string> address_map; 

address_map[Fred] = "1234 Evergreen Terrace"; 
address_map[Pete] = "4567 State Street"; 
address_map[Mark] = "123 North Street"; 

std::map<string,string>::const_iterator it = address_map.find(name); 
if(it == address_map.end()) doh(); 
std::cout << "You live at " << it->second << '\n'; 
0

我想你想实现某种形式的字典(图)结构,其中名称用户输入将是关键的。您可以将它映射为字符串 - >字符串,如果键位于地图中,则输出另一个字符串。

有很多方法来实现这一点,你可以手动或者你可以查找std :: map。

0

您的问题被标记为C++。在C++中,你可以只取关联数组的standrad实施和准备数据如下

#include <string> 
#include <map> 
... 
std::map<std::string, std::string> name2address; 
name2address["Fred"] = "1234 Evergreen Terrace"; 
name2address["Pete"] = "4567 State Street"; 
name2address["Mark"] = "123 North Street"; 

然后,一旦你的请求的名称

char Name[32]; 
gets(Name); 
// I leave it as is, but using `gets` is always nasty. And you might be much 
// better off with a 'std::string' instead in this case 

你可以找到addreess并打印

std::string address = name2address[Name]; 
// Add a check for whether it actually exists 

printf("You live at %s\n", address.c_str()); 
// Again, I leave `printf` as is 
0

根据你处理的其余部分有多复杂,你应该考虑把它们放到一个类中。一个班级也可以保留一个名字和地址。

class person 
{ 
    char[32] name; 
    char[32] address; 
    /* whatever else you need to know about the people */ 

    /* whatever functions you'd need to run on them */ 
} 

然后创建地图这些类的,再次使用的名称

std::map<string,person> person_list; 
0

你标记你的问题C++和C++ STL库,你可以使用地图容器中的名称映射到地址你的情况。下面您的问题的一些示例代码,使用STL字符串代替字符数组,你可能会发现最好:

// Set up your map 
#include <map> 
#include <string> 
using std; 

map<string, string> myMap; 

myMap["Fred"] = "1234 Evergreen Terrace"; 
myMap["Pete"] = "4567 State Street"; 
myMap["Mark"] = "123 North Street"; 

一旦你有你的地图设置,并且您已经阅读用户输入一个字符串变量名称,你会使用类似:

if(myMap.find(name) != myMap.end()) 
{ 
    printf("You live at %s\n", myMap[name].c_str()); 
} 
else 
{ 
    printf("I don't know where you live"); 
} 

希望帮助!

0

在编译时,Casting是从一件事物到另一件事物(主要是)强制执行的直接的,不可接受的转换。有:

  • 铸造内置可依法转变为每个-其他(的static_cast)类型。一个例子是int-> double转换:

    double d = 5.0; int i = static_cast(d);

  • 通知编译器将地址X处的数据视为不同类型(reinterpret_cast)。这与工会类似。

    struct消息 int header; int内容; // ... };

    char * myDataBuffer; 消息* decodedAsAMessage = reinterpret_cast(myDataBuffer)。

  • 有法律铸造向上/向下继承层次(dynamic_cast的):

    Base类 { };

    class Derrived:public Base { };

    Derrived * d = new Derrived(); 基数* b = dynamic_cast(d) 如果类型不相关,// b将为空。

  • 有从可变除去常量性,以便能够对其进行操作(的const_cast

    const int的大小= 5; int & sizeRef = const_cast(size); size ++;

  • 然后,您还会看到C风格的演员阵容,它更加模糊不清,并且不会明确告诉您或编译器明确发生了什么样的演员。

    double d = 5.0; int i =(int)(d);

有你的情况ou预计结果类型被格式化一个特定的方式。在上面的例子中,结果是非常明确的。没有办法指定如何在上面的示例中格式化结果字符串。你需要采取类似于你拥有的或者他们发布的方法。