2009-11-04 60 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預計結果類型被格式化一個特定的方式。在上面的例子中,結果是非常明確的。沒有辦法指定如何在上面的示例中格式化結果字符串。你需要採取類似於你擁有的或者他們發佈的方法。