turning string into int

Started by
20 comments, last by lancekt 17 years, 9 months ago
Quote:Original post by lancekt
Quote:Original post by Zahlman
What, because manually iterating over things, dealing with memory management on strings (granted there isn't any in the sample code, but presumably the string we're interested in "comes from somewhere" at runtime), etc. is "less complex"? Is this some kind of joke?


Any programmer alive can understand iteration over an array. There may be some who are (god forbid) unfamiliar with <algorithm> or even <string>.

Additionally, you are getting a pointer to the raw character data from the std::string in your version. The only real difference is that you have added an extra layer of complexity--the string class, which has no relevance whatever to this discussion.


See mikeman's post. I had a brainfart and missed the obvious thing, partly because of being distracted by these char*'s.

And lots of programmers "understand iteration over an array" in a completely different way. In Python, an explicit C++-style for loop would have to look like:

for i in range(len(container)):  do_something_with(container)


New users of Python get friendly jeers for this sort of thing, as the experiences Pythonistas attempt to correct the damage that other imperative languages have done to their thought process. Imagine, writing something that strange (and it doesn't even make you handle the incrementing like C++ would!), when you could do:

for thing in container:  do_something_with(thing)


Granted, C++ syntax can't be made quite so nice, but the library is a big step in that directly. Besides, the std::copy call reads quite naturally: "copy between str.begin() and 8 bytes after str.begin() to the reinterpreted-as-char* location of result". As opposed to "with i starting at zero until it reaches 8, incrementing each time, assign byte i of str to byte i of the reinterpreted-as-char* location of result".
Advertisement
Quote:Original post by methinks
I feel like an idiot, because I saw the answer here a while ago but now I can't seem to find it...

I'm storing data by identifier (using std::map). My problem is that the identifier comes in the form of a string, which (the way I understand it) is a slow way of doing it, because string comparisons take a while...

So what I would like to do is to change the string into a numerical value. A 64bit variable should be able to hold the equivalent of 8 chars, which should be sufficient. Now, how would I go about casting that?



You mean like this?

#ifndef _ID_STRING_H#define _ID_STRING_H#include <map>#include <string>class ID{private:    int id;public:        ID(){}    ID(int i);    ID(const std::string &Str);    ID(const char *ch);    bool operator ==(ID A) const;        bool operator !=(ID A) const;    bool operator < (ID A) const;    void operator = (const std::string &Str);    void operator = (const char *ch);};bool operator ==(const std::string &Str, ID Id);bool operator ==(ID Id, const std::string &Str);bool operator !=(const std::string &Str, ID Id);bool operator !=(ID Id, const std::string &Str);bool operator ==(const char *ch, ID Id);bool operator ==(ID Id, const char *ch);bool operator !=(const char *ch, ID Id);bool operator !=(ID Id, const char *ch);class ID_String{private:    ID_String();    static ID_String* instance;    std::map< std::string, ID, std::less<std::string> > Map;    int Pairs;        static const ID end;public:        //~ID_String();    static ID_String* Instance();    ID RegisterString(const std::string& name);    ID Ident(const std::string &name);    static ID End(){return end;}    std::string GetString(ID);};#endif //_ID_STRING_H


#include "ID_String.h"ID::ID(int i){    id = i;}ID::ID(const std::string &Str){    *this = (ID_String::Instance()->RegisterString(Str));}ID::ID(const char *ch){    std::string Str = ch;    *this = (ID_String::Instance()->RegisterString(Str));}bool ID::operator ==(ID A) const{    return id == A.id;}bool ID::operator !=(ID A) const{    return id != A.id;}bool ID::operator <(ID A) const{    return id < A.id;}void ID::operator =(const std::string &Str){    *this = (ID_String::Instance()->Ident(Str));}void ID::operator =(const char *ch){    std::string Str = ch;    *this = (ID_String::Instance()->Ident(Str));}bool operator ==(const std::string &Str, ID Id){    return Id == ID_String::Instance()->Ident(Str);}bool operator ==(ID Id, const std::string &Str){    return Id == ID_String::Instance()->Ident(Str);}bool operator !=(const std::string &Str, ID Id) {    return Id != ID_String::Instance()->Ident(Str);}bool operator !=(ID Id, const std::string &Str) {    return Id != ID_String::Instance()->Ident(Str);}bool operator ==(const char *ch, ID Id){    std::string Str = ch;    return Id == ID_String::Instance()->Ident(Str);}bool operator ==(ID Id, const char *ch){    std::string Str = ch;    return Id == ID_String::Instance()->Ident(Str);}bool operator !=(const char *ch, ID Id) {    std::string Str = ch;    return Id != ID_String::Instance()->Ident(Str);}bool operator !=(ID Id, const char *ch) {    std::string Str = ch;    return Id != ID_String::Instance()->Ident(Str);}ID_String* ID_String::instance = 0;const ID ID_String::end = ID(-1);ID_String::ID_String(){    Map.clear();    Pairs = 0;}//ID_String::~ID_String()//{//    if(instance) delete instance;//}ID_String* ID_String::Instance(){    if(instance == 0) instance = new ID_String();    return instance;}ID ID_String::RegisterString(const std::string& name){    std::map<std::string, ID>::iterator I = Map.find(name);    if(I != Map.end())    {        return I->second;    }    else    {        ID id(Pairs);        Map[name] = id;        Pairs++;        return id;;    }}ID ID_String::Ident(const std::string &name){    std::map<std::string,ID,std::less<std::string> >::iterator I = Map.find(name);    if(I != Map.end())    {        return I->second;    }    return this->end;}std::string ID_String::GetString(ID id){    std::map<std::string,ID,std::less<std::string> >::iterator I;    for(I = Map.begin(); I != Map.end(); ++I)    {        if(id == I->second)        {            return I->first;        }    }        return "";}
Quote:Original post by lancekt
Any programmer alive can understand iteration over an array. There may be some who are (god forbid) unfamiliar with <algorithm> or even <string>.


Learning the language syntax but not the standard library seems to be something only C++ programmers do. C, Java, Python, ($LANGUAGE) programmers all learn to use their respective language's library, but apparently, that's too much to ask of C++ programmers.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny
Quote:Original post by lancekt
Any programmer alive can understand iteration over an array. There may be some who are (god forbid) unfamiliar with <algorithm> or even <string>.


Learning the language syntax but not the standard library seems to be something only C++ programmers do. C, Java, Python, ($LANGUAGE) programmers all learn to use their respective language's library, but apparently, that's too much to ask of C++ programmers.


To be fair, the difference is that C++ provides both the C++ library and the C one, so people that come from C usually just learn the new syntax and continue to use stuff like printf(),memcpy(), because they can. There is not a single library, memcpy() is standard, std::copy() is standard. That makes it dificult for beginners to "detach" themselves from the way they used to do things in C.

But you'll notice that lancekt's code didn't use any of the appropriate C standard library functions either.
Wow, that's a lot of feedback, thanks!

A couple of questions:
What's reinterpret_cast, and more importantly, how is it different from static_cast?

How do I declare a 64bit int? (is it just _int64?)

Would I be able to just copy the string over one char at a time and then bitshift the int to the next int?
Quote:Original post by methinks
What's reinterpret_cast, and more importantly, how is it different from static_cast?


A static_cast is used when the two types are convertible one to the other, somehow, the cast performs the conversion appropriately: e.g. when cast to int, a float will be truncated. reinterpret_cast, on the other hand, tells the compiler to treat the variable as if it had been of the target type all along. Thus it reinterprets the same bundle of bit differently.

Quote:How do I declare a 64bit int? (is it just _int64?)


C++ does not (yet) have 64 bit integers. Compilers often support them as a language extension, but the keyword used vary. Visual Studio uses __int64, while GCC uses long long which, unless I am mistaken, is the way it is currently planned to be added.

Quote:Would I be able to just copy the string over one char at a time and then bitshift the int to the next int?


You could do that, but it's significantly more complicated. The solution you have now is the simple one: directly write the data in the right place. Bitshifting is not a good plan.
"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." — Brian W. Kernighan
Quote:Original post by Fruny

C++ does not (yet) have 64 bit integers. Compilers often support them as a language extension, but the keyword used vary. Visual Studio uses __int64, while GCC uses long long which, unless I am mistaken, is the way it is currently planned to be added.


With GCC compiling for a x86-64 system, longs are 64bits (as are long longs, ints are 32bits). I don't think the C++ standard guaranties any bit sizes, Just that sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long). So I think a standards compliant C++ compiler doesn't even need 32bit integers (I doubt such a compiler exists).

If I remember right __int64 works on Microsofts compiler and GCC (mingw). Which are the 2 most common ones.
Quote:Original post by Zahlman

New users of Python get friendly jeers for this sort of thing, as the experiences Pythonistas attempt to correct the damage that other imperative languages have done to their thought process. Imagine, writing something that strange (and it doesn't even make you handle the incrementing like C++ would!), when you could do:

for thing in container:  do_something_with(thing)


Granted, C++ syntax can't be made quite so nice...


Yes it can!

#include <boost/foreach.hpp>#include <vector>#include <iostream>#define foreach BOOST_FOREACHint main(){	std::vector<int> integers(10);	foreach(int& i, integers)		std::cout << i << " ";}


Btw, does anybody know how to change the syntax of the foreach macro so that it looks like this: foreach(int& i in integers)? I tried using

#define in ,

but that (obviously) didn't work.
deathkrushPS3/Xbox360 Graphics Programmer, Mass Media.Completed Projects: Stuntman Ignition (PS3), Saints Row 2 (PS3), Darksiders(PS3, 360)
Quote:Original post by Cocalus
Quote:Original post by Fruny

C++ does not (yet) have 64 bit integers. Compilers often support them as a language extension, but the keyword used vary. Visual Studio uses __int64, while GCC uses long long which, unless I am mistaken, is the way it is currently planned to be added.


With GCC compiling for a x86-64 system, longs are 64bits (as are long longs, ints are 32bits). I don't think the C++ standard guaranties any bit sizes, Just that sizeof(char)<=sizeof(short)<=sizeof(int)<=sizeof(long). So I think a standards compliant C++ compiler doesn't even need 32bit integers (I doubt such a compiler exists).

If I remember right __int64 works on Microsofts compiler and GCC (mingw). Which are the 2 most common ones.

Standard specify a minimum size of a type. All the type have size that are multiple of sizeof(char) that is 1. The header <limits.h> or <climits> contains information about the size dimensions and min/max values.
__int64 works on Microsofts compiler and mingw.

This topic is closed to new replies.

Advertisement