Is this casting?
Sorry for not even knowing what to title this, but here goes.
Suppose I have:
char Fred[] = "1234 Evergreen Terrace";
char Pete[] = "4567 State Street";
c开发者_Go百科har Mark[] = "123 North Street";
char Name[32];
gets(Name);
instead of writing:
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);
Isn't there a way to skip all the strcmps() by writing:
printf("You live at %s\n",<SOMETHING_HERE>Name)
My needs are more complex but the above simple example should get me going. It's been nearly 15 years since I learned about it but I just can't recall. Thanks in advance! Dan
- Use an std::map of string--> string.
- Take a string from the input
- if it is in the map, print it
Sample:
#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;
}
Look 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];
}
What you need is a map. A data structure that will map your names -> addresses.
Try making a structure like this:
struct person {
char name[32];
char address[256];
}
Then create an array of person structures:
struct person[] = {
{"fred", "1234 Evergreen Terrace"},
{"pete", "4567 State Street"},
{"mark", "123 North Street"}
};
int numberOfPeople = 3;
Then when you need to find one you can search it this way:
for(int index = 0; index < numberOfPeople; index++) {
if(!strcmp(person[index].name, name)) {
printf("You live at %s.\n");
}
}
Obviously there are many more advanced ways of doing this. I'd suggest reading up on classes and hashmaps. A class is a more advanced version of a structure that allows you to do all sorts of neat stuff. A hash map is a data structure that uses something called a hash function to use your string as a key that finds the correct address.
Or rather than learning about exactly how maps work and making your own, you could always be lazy and just use std::map ;)
You could store the names and addresses in an associative container such as an STL map with the name being the key and the address being the value.
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";
Then the single 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);
Note that you need to check for the case where the name does not already exist within the map - e.g. using find() as shown above.
Isn't there a way to skip all the
strcmp()
?
In C++, this is spelled 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';
I suppose you'd want to implement some sort of dictionary (map) structure, where the name user inputs would be a key. You'd map it as string->string and if the key is in the map, then output the other string.
There are many ways of implementing this, you can do it by hand or you can look up std::map.
Your question is tagged C++. In C++ you can just take a standrad implementation of associative array and prepare your data as follows
#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";
Then, once you have the requested name
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
you can find the addreess and print it
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
Depending on how complicated the rest of what you're dealing with is, you should consider putting these into a class. A class can keep a name and address associated with each other as well.
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 */
}
then create a map of these classes, again using the name
std::map<string,person> person_list;
Casting is the direct, unambigous, conversion from one thing to another thing enforced (mostly) at compile time. There's:
Casting of built-in types that can be legally converted to each-other (static_cast). An example to this is int->double conversion:
double d = 5.0; int i = static_cast(d);
Telling the compiler to treat the data at address X like a different type (reinterpret_cast). This is similar to a union.
struct Message { int header; int contents; //... };
char* myDataBuffer; Message* interpretedAsAMessage = reinterpret_cast(myDataBuffer).
There's legal casting up/down an inheritance hierarchy (dynamic_cast):
class Base { };
class Derrived : public Base { };
Derrived* d = new Derrived(); Base* b = dynamic_cast(d) // b will be null if types aren't related.
There's removing constness from a variable to be able to manipulate it (const_cast)
const int size = 5; int& sizeRef = const_cast(size); size++;
Then you'll also see the C-style cast, which is more ambigous, and doesn't tell you or the compiler explicitly what kind of cast is happening.
double d = 5.0; int i = (int)(d);
There' In your case ou expect the resultant type to be formatted a specific way. In the above examples, the result is unambigous and clear. There's no way to specify how a resultant string would be formatted in the above examples. You need to take an approach similar to what you have or what thers have posted.
You tagged your question C++, and in the C++ STL library you can use the map container to map names to addresses in your case. Some example code for your problem below, using the STL string instead of char arrays, which you may find preferable:
// 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";
And once you have your map set up, and you've read the user input into a string variable name, you would use something like:
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");
}
Hope that helps!
精彩评论