map (associative array) loses values?

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jeroenvlek@gmail.com

    #1

    map (associative array) loses values?

    Hi there,

    I've never done this before, so I don't know about any layout
    possibilities. My apologies :)

    The problem is this:

    I've written a function:

    map<const char*, int*SearchText: :countWords()
    {
    map<const char*, int*table = new map<const char*, int>;

    (*table)["aap"] = 1;
    (*table)["noot"] = 2;

    cout << (*table)["aap"] << endl;
    cout << (*table)["noot"] << endl;

    return table;
    }

    Which I want to use like this:

    try {
    SearchText *text = new SearchText("tes t.txt");
    map<const char*, int*table = text->countWords() ;
    cout << (*table)["aap"] << endl;
    cout << (*table)["noot"] << endl;
    }
    catch(int ex) {
    cout << "Could not open file." << endl;
    }


    However, I get the following output:

    1
    2
    0
    0

    Meaning that the first two output statements (in the function itself)
    do their job and the second two do not.

    I guess it's some sort of allocation problem, but what could I do
    different? I guess I could use maybe malloc or calloc, but shouldn't
    this be also possible with new?

    BTW making table static in the function didn't help.

  • Pete Becker

    #2
    Re: map (associative array) loses values?

    On 2007-09-11 11:42:18 -0400, jeroenvlek@gmai l.com said:
    Hi there,
    >
    I've never done this before, so I don't know about any layout
    possibilities. My apologies :)
    >
    The problem is this:
    >
    I've written a function:
    >
    map<const char*, int*SearchText: :countWords()
    {
    map<const char*, int*table = new map<const char*, int>;
    There's no reason to create this map on the heap. Make it a local
    >
    (*table)["aap"] = 1;
    (*table)["noot"] = 2;
    >
    cout << (*table)["aap"] << endl;
    cout << (*table)["noot"] << endl;
    >
    return table;
    }
    >
    Which I want to use like this:
    >
    try {
    SearchText *text = new SearchText("tes t.txt");
    map<const char*, int*table = text->countWords() ;
    cout << (*table)["aap"] << endl;
    cout << (*table)["noot"] << endl;
    }
    catch(int ex) {
    cout << "Could not open file." << endl;
    }
    >
    >
    However, I get the following output:
    >
    1
    2
    0
    0
    >
    Meaning that the first two output statements (in the function itself)
    do their job and the second two do not.
    >
    I guess it's some sort of allocation problem, but what could I do
    different? I guess I could use maybe malloc or calloc, but shouldn't
    this be also possible with new?
    >
    BTW making table static in the function didn't help.

    --
    Pete
    Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
    Standard C++ Library Extensions: a Tutorial and Reference
    (www.petebecker.com/tr1book)

    Comment

    • Pete Becker

      #3
      Re: map (associative array) loses values?

      On 2007-09-11 11:47:36 -0400, Pete Becker <pete@versatile coding.comsaid:
      On 2007-09-11 11:42:18 -0400, jeroenvlek@gmai l.com said:
      >
      >Hi there,
      >>
      >I've never done this before, so I don't know about any layout
      >possibilitie s. My apologies :)
      >>
      >The problem is this:
      >>
      >I've written a function:
      >>
      >map<const char*, int*SearchText: :countWords()
      >{
      > map<const char*, int*table = new map<const char*, int>;
      >
      There's no reason to create this map on the heap. Make it a local
      >
      Ignore this. Posted too soon. :-(

      --
      Pete
      Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
      Standard C++ Library Extensions: a Tutorial and Reference
      (www.petebecker.com/tr1book)

      Comment

      • Kai-Uwe Bux

        #4
        Re: map (associative array) loses values?

        jeroenvlek@gmai l.com wrote:
        Hi there,
        >
        I've never done this before, so I don't know about any layout
        possibilities. My apologies :)
        >
        The problem is this:
        >
        I've written a function:
        >
        map<const char*, int*SearchText: :countWords()
        {
        map<const char*, int*table = new map<const char*, int>;
        >
        (*table)["aap"] = 1;
        (*table)["noot"] = 2;
        >
        cout << (*table)["aap"] << endl;
        cout << (*table)["noot"] << endl;
        >
        return table;
        }
        >
        Which I want to use like this:
        >
        try {
        SearchText *text = new SearchText("tes t.txt");
        map<const char*, int*table = text->countWords() ;
        cout << (*table)["aap"] << endl;
        cout << (*table)["noot"] << endl;
        }
        catch(int ex) {
        cout << "Could not open file." << endl;
        }
        >
        >
        However, I get the following output:
        >
        1
        2
        0
        0
        >
        Meaning that the first two output statements (in the function itself)
        do their job and the second two do not.
        >
        I guess it's some sort of allocation problem,
        nope.

        The problem is the data structure

        map< char*, ... >

        Note that this will (a) store pointers to char and (b) compare those
        pointers (not the strings pointed to) to identify keys. Also note that two
        different string literals "aap" are _not_ guaranteed to be represented by
        the same char*. That is why you don't find the recorded entries.

        but what could I do different?
        Use map< std::string, ... instead. That will store and compare values.

        I guess I could use maybe malloc or calloc, but shouldn't this be also
        possible with new?
        On that note: why do you do dynamic allocation of the map anyway? Your code
        is littered with new() for no reason (and it misses the corresponding
        delete statements, too).

        BTW making table static in the function didn't help.
        It is not expected to.


        Best

        Kai-Uwe Bux

        Comment

        • jeroenvlek@gmail.com

          #5
          Re: map (associative array) loses values?

          On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
          <cut>
          >
          Best
          >
          Kai-Uwe Bux
          ah, ok. <string, intworks like a charm! :)

          I'm using new, because I need the table somewhere else. The try/catch
          is in my main, while the function resides in the SearchText class. The
          delete statements are there, I just didn't post them ;)

          Ofcourse I'm just a c++ newbie (this is my first program actually), so
          what would you do different?

          Comment

          • Jim Langston

            #6
            Re: map (associative array) loses values?

            <jeroenvlek@gma il.comwrote in message
            news:1189527328 .279612.21880@1 9g2000hsx.googl egroups.com...
            On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
            <cut>
            >>
            >Best
            >>
            >Kai-Uwe Bux
            >
            ah, ok. <string, intworks like a charm! :)
            >
            I'm using new, because I need the table somewhere else. The try/catch
            is in my main, while the function resides in the SearchText class. The
            delete statements are there, I just didn't post them ;)
            >
            Ofcourse I'm just a c++ newbie (this is my first program actually), so
            what would you do different?
            Just because you need the map somewhere else doesn't mean you should new it.
            The standard containers are actually quite small in and of themselves. If
            you need the map somewhere else, you are passing the pointer to it, correct?
            So just pass the pointer, or better yet, a reference to it. Creating the
            map in the function is not the best method.

            Consider this untested code:

            class SearchText
            {
            public:
            std::map<std::s tring, int>& countWords();
            private:
            std::map<std::s tring, inttable;
            }

            std::map<std::s tring, int>& SearchText::cou ntWords()
            {
            table["aap"] = 1;
            table["noot"] = 2;

            return table;
            }

            int main()
            {
            try
            {
            SearchText text("test.txt" );
            std::map<std::s tring, int>& table = text.countWords ();

            std::cout << table["aap"] << "\n" << table["noot"] << std::endl;
            }
            catch(int ex )
            {
            std::cout << "Could not open file" << std::endl;
            }
            }

            This is just trying to show that you don't have to new everything, in fact,
            you shouldn't when you don't have to.


            Comment

            • BobR

              #7
              Re: map (associative array) loses values?


              <jeroenvlek@gma il.comwrote in message...
              On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
              <cut>
              >
              ah, ok. <string, intworks like a charm! :)
              >
              I'm using new, because I need the table somewhere else. The try/catch
              is in my main, while the function resides in the SearchText class. The
              delete statements are there, I just didn't post them ;)
              >
              Ofcourse I'm just a c++ newbie (this is my first program actually), so
              what would you do different?
              >
              An alternative to Jim's suggestion:

              // pass by non-const reference.
              void SearchText::cou ntWords( std::map<std::s tring, int&map ){
              map["aap"] = 1;
              map["noot"] = 2;

              std::cout << map["aap"] << std::endl;
              std::cout << map["noot"] << std::endl;
              return;
              }

              // int main(){
              try {

              std::map<std::s tring, intMyMap;

              SearchText text("test.txt" );
              text.countWords ( MyMap );
              std::cout << MyMap["aap"] << std::endl;
              std::cout << MyMap["noot"] << std::endl;
              }
              catch( int ex) {
              cout << "Could not open file." << endl;
              }
              // return 0;
              // } // main()

              Sorry, I didn't test that. Post back if you have trouble ( I may have missed
              something. <G>).

              --
              Bob R
              POVrookie


              Comment

              • Kai-Uwe Bux

                #8
                Re: map (associative array) loses values?

                jeroenvlek@gmai l.com wrote:
                On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                <cut>
                >>
                >Best
                >>
                >Kai-Uwe Bux
                >
                ah, ok. <string, intworks like a charm! :)
                >
                I'm using new, because I need the table somewhere else. The try/catch
                is in my main, while the function resides in the SearchText class. The
                delete statements are there, I just didn't post them ;)
                >
                Ofcourse I'm just a c++ newbie (this is my first program actually), so
                what would you do different?
                I would start with something like

                map<const std::string, intSearchText:: countWords()
                {
                map<std::string , intresult;

                result["aap"] = 1;
                result["noot"] = 2;

                cout << result["aap"] << endl;
                cout << result["noot"] << endl;

                return result;
                }

                and later

                try {
                SearchText text ("test.txt") ;
                map<const std::string, inttable = text->countWords() ; // *
                cout << table["aap"] << endl;
                cout << table["noot"] << endl;
                }
                catch(int ex) {
                cout << "Could not open file." << endl;
                }


                That is, on the first try, I would leave it to the compiler to optimize away
                the apparent copy-construction in line (*). If profiling shows that the
                compiler does not eliminate the copy-constructor calls _and_ that there is
                a need to improve performance, I might change the program:


                void SearchText::cou ntWords( map<std::string , int& result ) {
                result["aap"] = 1;
                result["noot"] = 2;

                cout << result["aap"] << endl;
                cout << result["noot"] << endl;
                }

                ....

                try {
                SearchText text ("test.txt") ;
                map<const std::string, inttable;
                text->countWords( table );
                cout << table["aap"] << endl;
                cout << table["noot"] << endl;
                }
                catch(int ex) {
                cout << "Could not open file." << endl;
                }


                or I might resort to swap() tricks (faking move semantics):


                map<const std::string, intSearchText:: countWords()
                {
                map<std::string , intresult;

                result["aap"] = 1;
                result["noot"] = 2;

                cout << result["aap"] << endl;
                cout << result["noot"] << endl;

                return result;
                }

                ....

                try {
                SearchText text ("test.txt") ;
                map<const std::string, inttable;
                text->countWords().s wap( table );
                cout << table["aap"] << endl;
                cout << table["noot"] << endl;
                }
                catch(int ex) {
                cout << "Could not open file." << endl;
                }


                Also: I would have the constructor of SearchText throw something more
                meaningfull than an int.


                Best

                Kai-Uwe Bux

                Comment

                • Jim Langston

                  #9
                  Re: map (associative array) loses values?

                  "BobR" <removeBadBobR@ worldnet.att.ne twrote in message
                  news:IMAFi.5272 07$p47.503263@b gtnsc04-news.ops.worldn et.att.net...
                  >
                  <jeroenvlek@gma il.comwrote in message...
                  >On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                  ><cut>
                  >>
                  >ah, ok. <string, intworks like a charm! :)
                  >>
                  >I'm using new, because I need the table somewhere else. The try/catch
                  >is in my main, while the function resides in the SearchText class. The
                  >delete statements are there, I just didn't post them ;)
                  >>
                  >Ofcourse I'm just a c++ newbie (this is my first program actually), so
                  >what would you do different?
                  >>
                  >
                  An alternative to Jim's suggestion:
                  >
                  // pass by non-const reference.
                  void SearchText::cou ntWords( std::map<std::s tring, int&map ){
                  map["aap"] = 1;
                  map["noot"] = 2;
                  >
                  std::cout << map["aap"] << std::endl;
                  std::cout << map["noot"] << std::endl;
                  return;
                  }
                  >
                  // int main(){
                  try {
                  >
                  std::map<std::s tring, intMyMap;
                  >
                  SearchText text("test.txt" );
                  text.countWords ( MyMap );
                  std::cout << MyMap["aap"] << std::endl;
                  std::cout << MyMap["noot"] << std::endl;
                  }
                  catch( int ex) {
                  cout << "Could not open file." << endl;
                  }
                  // return 0;
                  // } // main()
                  >
                  Sorry, I didn't test that. Post back if you have trouble ( I may have
                  missed
                  something. <G>).
                  There are a lot of alternatives to mine and Bob's suggestion. In fact, if I
                  was designing this class myself I would totally encapsulate the map inside
                  the class and main would only get to it via functions. Depending on what it
                  would be for something like (untested code)

                  class SearchText
                  {
                  public:
                  SearchText( const std::string& FileName );
                  int Value( const std::string& key ) const;
                  int CountWords();
                  private:
                  std::map<std::s tring, intData_;
                  }

                  SearchText::Sea rchText( const std::string& FileName )
                  {
                  // Open file and load Data_
                  }

                  int Value( const std::string& Key ) const
                  {
                  if ( Data_.find( Key ) != Data_.end() )
                  return Data_[Key];
                  else
                  return 0;
                  }

                  int CountWords()
                  {
                  // Return whatever it is this is trying to count
                  }

                  I am a strong believe in data encapsulation in classes, and try to always
                  prevent giving points or references to my internal classes data. Anything
                  you need the map for in mian you can encapsulate. Even encapsulate
                  operator[] if you wish.

                  int SearchText::ope rator[]( const std::string& Key )
                  {
                  return Value( Key );
                  }


                  Comment

                  • jeroenvlek@gmail.com

                    #10
                    Re: map (associative array) loses values?

                    On 11 sep, 21:35, "Jim Langston" <tazmas...@rock etmail.comwrote :
                    "BobR" <removeBadB...@ worldnet.att.ne twrote in message
                    >
                    news:IMAFi.5272 07$p47.503263@b gtnsc04-news.ops.worldn et.att.net...
                    >
                    >
                    >
                    >
                    >
                    >
                    >
                    <jeroenv...@gma il.comwrote in message...
                    On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                    <cut>
                    >
                    ah, ok. <string, intworks like a charm! :)
                    >
                    I'm using new, because I need the table somewhere else. The try/catch
                    is in my main, while the function resides in the SearchText class. The
                    delete statements are there, I just didn't post them ;)
                    >
                    Ofcourse I'm just a c++ newbie (this is my first program actually), so
                    what would you do different?
                    >
                    An alternative to Jim's suggestion:
                    >
                    // pass by non-const reference.
                    void SearchText::cou ntWords( std::map<std::s tring, int&map ){
                    map["aap"] = 1;
                    map["noot"] = 2;
                    >
                    std::cout << map["aap"] << std::endl;
                    std::cout << map["noot"] << std::endl;
                    return;
                    }
                    >
                    // int main(){
                    try {
                    >
                    std::map<std::s tring, intMyMap;
                    >
                    SearchText text("test.txt" );
                    text.countWords ( MyMap );
                    std::cout << MyMap["aap"] << std::endl;
                    std::cout << MyMap["noot"] << std::endl;
                    }
                    catch( int ex) {
                    cout << "Could not open file." << endl;
                    }
                    // return 0;
                    // } // main()
                    >
                    Sorry, I didn't test that. Post back if you have trouble ( I may have
                    missed
                    something. <G>).
                    >
                    There are a lot of alternatives to mine and Bob's suggestion. In fact, if I
                    was designing this class myself I would totally encapsulate the map inside
                    the class and main would only get to it via functions. Depending on what it
                    would be for something like (untested code)
                    >
                    class SearchText
                    {
                    public:
                    SearchText( const std::string& FileName );
                    int Value( const std::string& key ) const;
                    int CountWords();
                    private:
                    std::map<std::s tring, intData_;
                    >
                    }
                    >
                    SearchText::Sea rchText( const std::string& FileName )
                    {
                    // Open file and load Data_
                    >
                    }
                    >
                    int Value( const std::string& Key ) const
                    {
                    if ( Data_.find( Key ) != Data_.end() )
                    return Data_[Key];
                    else
                    return 0;
                    >
                    }
                    >
                    int CountWords()
                    {
                    // Return whatever it is this is trying to count
                    >
                    }
                    >
                    I am a strong believe in data encapsulation in classes, and try to always
                    prevent giving points or references to my internal classes data. Anything
                    you need the map for in mian you can encapsulate. Even encapsulate
                    operator[] if you wish.
                    >
                    int SearchText::ope rator[]( const std::string& Key )
                    {
                    return Value( Key );
                    >
                    >
                    >
                    }- Tekst uit oorspronkelijk bericht niet weergeven -
                    >
                    - Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk bericht niet weergeven -
                    >
                    - Tekst uit oorspronkelijk bericht weergeven -

                    Thanks a lot you guys for all the reactions!

                    The reason why I did not want to copy the entire map, was because I'm
                    going to use it for counting the words in



                    which is a 3,3 mb text file. ;)

                    However, as Jim Langston already mentioned (and maybe you too Kai-Uwe
                    Bux, I'm going to study your examples more closely), I can encapsulate
                    this map into the SearchText class, since the map and the file are
                    related and there is no need to seperate them. Any possible new file
                    will need a new instance of SearchText anyway.

                    Thanks a lot though. I never worked via this principle of newsgroups,
                    but I'm going to have a look here more often!

                    For those of you interested: I need this for the first assignment of a
                    Natural Language Processing course (at University of Amsterdam) and
                    next assignments will build on this one, so I wanted to make this
                    stuff so generic as possible. Some of you now might say: Use Python!
                    But I really want to learn C++ (and I would have to learn Python
                    too...) and the only way to do this is by programming :)

                    Thanks again.

                    Jeroen

                    Comment

                    • BobR

                      #11
                      Re: map (associative array) loses values?


                      Jim Langston wrote in message...
                      >
                      class SearchText
                      {
                      public:
                      SearchText( const std::string& FileName );
                      int Value( const std::string& key ) const;
                      int CountWords();
                      private:
                      std::map<std::s tring, intData_;
                      }
                      Oh Lord, what's this world comeing to?!?

                      Do you realize you could be appointed to the U.S. Supreme Court by the bush
                      admin for leaving off the critical semicolon at the end of the class decl?!?

                      <G>

                      Otherwise, I agree.

                      #include <iostream>
                      int main(){
                      std::cout<< " Hi Jim. :-} " <<std::endl;
                      return 0;
                      }
                      --
                      Bob R
                      POVrookie


                      Comment

                      • Jim Langston

                        #12
                        Re: map (associative array) loses values?

                        <jeroenvlek@gma il.comwrote in message
                        news:1189542044 .096744.201450@ e34g2000pro.goo glegroups.com.. .
                        On 11 sep, 21:35, "Jim Langston" <tazmas...@rock etmail.comwrote :
                        >"BobR" <removeBadB...@ worldnet.att.ne twrote in message
                        >>
                        >news:IMAFi.527 207$p47.503263@ bgtnsc04-news.ops.worldn et.att.net...
                        >>
                        >>
                        >>
                        >>
                        >>
                        >>
                        >>
                        <jeroenv...@gma il.comwrote in message...
                        >On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                        ><cut>
                        >>
                        >ah, ok. <string, intworks like a charm! :)
                        >>
                        >I'm using new, because I need the table somewhere else. The try/catch
                        >is in my main, while the function resides in the SearchText class. The
                        >delete statements are there, I just didn't post them ;)
                        >>
                        >Ofcourse I'm just a c++ newbie (this is my first program actually), so
                        >what would you do different?
                        >>
                        An alternative to Jim's suggestion:
                        >>
                        // pass by non-const reference.
                        void SearchText::cou ntWords( std::map<std::s tring, int&map ){
                        map["aap"] = 1;
                        map["noot"] = 2;
                        >>
                        std::cout << map["aap"] << std::endl;
                        std::cout << map["noot"] << std::endl;
                        return;
                        }
                        >>
                        // int main(){
                        try {
                        >>
                        std::map<std::s tring, intMyMap;
                        >>
                        SearchText text("test.txt" );
                        text.countWords ( MyMap );
                        std::cout << MyMap["aap"] << std::endl;
                        std::cout << MyMap["noot"] << std::endl;
                        }
                        catch( int ex) {
                        cout << "Could not open file." << endl;
                        }
                        // return 0;
                        // } // main()
                        >>
                        Sorry, I didn't test that. Post back if you have trouble ( I may have
                        missed
                        something. <G>).
                        >>
                        >There are a lot of alternatives to mine and Bob's suggestion. In fact,
                        >if I
                        >was designing this class myself I would totally encapsulate the map
                        >inside
                        >the class and main would only get to it via functions. Depending on what
                        >it
                        >would be for something like (untested code)
                        >>
                        >class SearchText
                        >{
                        >public:
                        > SearchText( const std::string& FileName );
                        > int Value( const std::string& key ) const;
                        > int CountWords();
                        >private:
                        > std::map<std::s tring, intData_;
                        >>
                        >}
                        >>
                        >SearchText::Se archText( const std::string& FileName )
                        >{
                        > // Open file and load Data_
                        >>
                        >}
                        >>
                        >int Value( const std::string& Key ) const
                        >{
                        > if ( Data_.find( Key ) != Data_.end() )
                        > return Data_[Key];
                        > else
                        > return 0;
                        >>
                        >}
                        >>
                        >int CountWords()
                        >{
                        > // Return whatever it is this is trying to count
                        >>
                        >}
                        >>
                        >I am a strong believe in data encapsulation in classes, and try to always
                        >prevent giving points or references to my internal classes data.
                        >Anything
                        >you need the map for in mian you can encapsulate. Even encapsulate
                        >operator[] if you wish.
                        >>
                        >int SearchText::ope rator[]( const std::string& Key )
                        >{
                        > return Value( Key );
                        >>
                        >>
                        >>
                        >}- Tekst uit oorspronkelijk bericht niet weergeven -
                        >>
                        >- Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk
                        >bericht niet weergeven -
                        >>
                        >- Tekst uit oorspronkelijk bericht weergeven -
                        >
                        >
                        Thanks a lot you guys for all the reactions!
                        >
                        The reason why I did not want to copy the entire map, was because I'm
                        going to use it for counting the words in
                        >

                        >
                        which is a 3,3 mb text file. ;)
                        >
                        However, as Jim Langston already mentioned (and maybe you too Kai-Uwe
                        Bux, I'm going to study your examples more closely), I can encapsulate
                        this map into the SearchText class, since the map and the file are
                        related and there is no need to seperate them. Any possible new file
                        will need a new instance of SearchText anyway.
                        >
                        Thanks a lot though. I never worked via this principle of newsgroups,
                        but I'm going to have a look here more often!
                        >
                        For those of you interested: I need this for the first assignment of a
                        Natural Language Processing course (at University of Amsterdam) and
                        next assignments will build on this one, so I wanted to make this
                        stuff so generic as possible. Some of you now might say: Use Python!
                        But I really want to learn C++ (and I would have to learn Python
                        too...) and the only way to do this is by programming :)
                        I can understand not wanting to copy the map being 3.3 megabytes. Be aware,
                        however, that if you copy your class, the map will get copied also. So just
                        make sure you pass your class by reference than by value. One way to ensure
                        this is to disable copying of your class. The normal way to do this is to
                        create a copy constructor ( and assignment operator) and make them private
                        to the class. That way if you accidently write some code that would create
                        a copy of the class, it won't compile and you will realize it.

                        For the SearchText class that would be:

                        class SearchText
                        {
                        public:
                        // ...
                        private:

                        // Disable copy and assignment by making private.
                        SearchText( SearchText const&) {}
                        SearchText& operator=( SearchText const&) {}
                        }

                        Just empty copy constructor and assignment operator's private to the class.


                        Comment

                        • Jim Langston

                          #13
                          Re: map (associative array) loses values?

                          "Jim Langston" <tazmaster@rock etmail.comwrote in message
                          news:l6DFi.586$ 6k3.1@newsfe06. lga...
                          <jeroenvlek@gma il.comwrote in message
                          news:1189542044 .096744.201450@ e34g2000pro.goo glegroups.com.. .
                          >On 11 sep, 21:35, "Jim Langston" <tazmas...@rock etmail.comwrote :
                          >>"BobR" <removeBadB...@ worldnet.att.ne twrote in message
                          >>>
                          >>news:IMAFi.52 7207$p47.503263 @bgtnsc04-news.ops.worldn et.att.net...
                          >>>
                          >>>
                          >>>
                          >>>
                          >>>
                          >>>
                          >>>
                          ><jeroenv...@gm ail.comwrote in message...
                          >>On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                          >><cut>
                          >>>
                          >>ah, ok. <string, intworks like a charm! :)
                          >>>
                          >>I'm using new, because I need the table somewhere else. The try/catch
                          >>is in my main, while the function resides in the SearchText class.
                          >>The
                          >>delete statements are there, I just didn't post them ;)
                          >>>
                          >>Ofcourse I'm just a c++ newbie (this is my first program actually),
                          >>so
                          >>what would you do different?
                          >>>
                          >An alternative to Jim's suggestion:
                          >>>
                          >// pass by non-const reference.
                          >void SearchText::cou ntWords( std::map<std::s tring, int&map ){
                          > map["aap"] = 1;
                          > map["noot"] = 2;
                          >>>
                          > std::cout << map["aap"] << std::endl;
                          > std::cout << map["noot"] << std::endl;
                          > return;
                          > }
                          >>>
                          >// int main(){
                          > try {
                          >>>
                          > std::map<std::s tring, intMyMap;
                          >>>
                          > SearchText text("test.txt" );
                          > text.countWords ( MyMap );
                          > std::cout << MyMap["aap"] << std::endl;
                          > std::cout << MyMap["noot"] << std::endl;
                          > }
                          > catch( int ex) {
                          > cout << "Could not open file." << endl;
                          > }
                          >// return 0;
                          >// } // main()
                          >>>
                          >Sorry, I didn't test that. Post back if you have trouble ( I may have
                          >missed
                          >something. <G>).
                          >>>
                          >>There are a lot of alternatives to mine and Bob's suggestion. In fact,
                          >>if I
                          >>was designing this class myself I would totally encapsulate the map
                          >>inside
                          >>the class and main would only get to it via functions. Depending on
                          >>what it
                          >>would be for something like (untested code)
                          >>>
                          >>class SearchText
                          >>{
                          >>public:
                          >> SearchText( const std::string& FileName );
                          >> int Value( const std::string& key ) const;
                          >> int CountWords();
                          >>private:
                          >> std::map<std::s tring, intData_;
                          >>>
                          >>}
                          >>>
                          >>SearchText::S earchText( const std::string& FileName )
                          >>{
                          >> // Open file and load Data_
                          >>>
                          >>}
                          >>>
                          >>int Value( const std::string& Key ) const
                          >>{
                          >> if ( Data_.find( Key ) != Data_.end() )
                          >> return Data_[Key];
                          >> else
                          >> return 0;
                          >>>
                          >>}
                          >>>
                          >>int CountWords()
                          >>{
                          >> // Return whatever it is this is trying to count
                          >>>
                          >>}
                          >>>
                          >>I am a strong believe in data encapsulation in classes, and try to
                          >>always
                          >>prevent giving points or references to my internal classes data.
                          >>Anything
                          >>you need the map for in mian you can encapsulate. Even encapsulate
                          >>operator[] if you wish.
                          >>>
                          >>int SearchText::ope rator[]( const std::string& Key )
                          >>{
                          >> return Value( Key );
                          >>>
                          >>>
                          >>>
                          >>}- Tekst uit oorspronkelijk bericht niet weergeven -
                          >>>
                          >>- Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk
                          >>bericht niet weergeven -
                          >>>
                          >>- Tekst uit oorspronkelijk bericht weergeven -
                          >>
                          >>
                          >Thanks a lot you guys for all the reactions!
                          >>
                          >The reason why I did not want to copy the entire map, was because I'm
                          >going to use it for counting the words in
                          >>
                          >http://www-nlp.stanford.edu/fsnlp/statest/austen.txt
                          >>
                          >which is a 3,3 mb text file. ;)
                          >>
                          >However, as Jim Langston already mentioned (and maybe you too Kai-Uwe
                          >Bux, I'm going to study your examples more closely), I can encapsulate
                          >this map into the SearchText class, since the map and the file are
                          >related and there is no need to seperate them. Any possible new file
                          >will need a new instance of SearchText anyway.
                          >>
                          >Thanks a lot though. I never worked via this principle of newsgroups,
                          >but I'm going to have a look here more often!
                          >>
                          >For those of you interested: I need this for the first assignment of a
                          >Natural Language Processing course (at University of Amsterdam) and
                          >next assignments will build on this one, so I wanted to make this
                          >stuff so generic as possible. Some of you now might say: Use Python!
                          >But I really want to learn C++ (and I would have to learn Python
                          >too...) and the only way to do this is by programming :)
                          >
                          I can understand not wanting to copy the map being 3.3 megabytes. Be
                          aware, however, that if you copy your class, the map will get copied also.
                          So just make sure you pass your class by reference than by value. One way
                          to ensure this is to disable copying of your class. The normal way to do
                          this is to create a copy constructor ( and assignment operator) and make
                          them private to the class. That way if you accidently write some code
                          that would create a copy of the class, it won't compile and you will
                          realize it.
                          >
                          For the SearchText class that would be:
                          >
                          class SearchText
                          {
                          public:
                          // ...
                          private:
                          >
                          // Disable copy and assignment by making private.
                          SearchText( SearchText const&) {}
                          SearchText& operator=( SearchText const&) {}
                          }
                          >
                          Just empty copy constructor and assignment operator's private to the
                          class.
                          Just a note. I noticed in that code that in operator= I don't have a return
                          statement. I looked in my own code where I'm doing this same thing and also
                          don't have a return statement. I don't know if that's a compiler flaw not
                          catching it, or the standard allows it. I think, however, that
                          SearchText& opeator=( SearchText const& ) { return this; }
                          would be more correct, even though it will never be called.


                          Comment

                          • jeroenvlek@gmail.com

                            #14
                            Re: map (associative array) loses values?

                            On Sep 11, 10:49 pm, "Jim Langston" <tazmas...@rock etmail.comwrote :
                            "Jim Langston" <tazmas...@rock etmail.comwrote in message
                            >
                            news:l6DFi.586$ 6k3.1@newsfe06. lga...
                            >
                            >
                            >
                            <jeroenv...@gma il.comwrote in message
                            news:1189542044 .096744.201450@ e34g2000pro.goo glegroups.com.. .
                            On 11 sep, 21:35, "Jim Langston" <tazmas...@rock etmail.comwrote :
                            >"BobR" <removeBadB...@ worldnet.att.ne twrote in message
                            >
                            >>news:IMAFi.52 7207$p47.503263 @bgtnsc04-news.ops.worldn et.att.net...
                            >
                            <jeroenv...@gma il.comwrote in message...
                            >On Sep 11, 5:59 pm, Kai-Uwe Bux <jkherci...@gmx .netwrote:
                            ><cut>
                            >
                            >ah, ok. <string, intworks like a charm! :)
                            >
                            >I'm using new, because I need the table somewhere else. The try/catch
                            >is in my main, while the function resides in the SearchText class.
                            >The
                            >delete statements are there, I just didn't post them ;)
                            >
                            >Ofcourse I'm just a c++ newbie (this is my first program actually),
                            >so
                            >what would you do different?
                            >
                            An alternative to Jim's suggestion:
                            >
                            // pass by non-const reference.
                            void SearchText::cou ntWords( std::map<std::s tring, int&map ){
                            map["aap"] = 1;
                            map["noot"] = 2;
                            >
                            std::cout << map["aap"] << std::endl;
                            std::cout << map["noot"] << std::endl;
                            return;
                            }
                            >
                            // int main(){
                            try {
                            >
                            std::map<std::s tring, intMyMap;
                            >
                            SearchText text("test.txt" );
                            text.countWords ( MyMap );
                            std::cout << MyMap["aap"] << std::endl;
                            std::cout << MyMap["noot"] << std::endl;
                            }
                            catch( int ex) {
                            cout << "Could not open file." << endl;
                            }
                            // return 0;
                            // } // main()
                            >
                            Sorry, I didn't test that. Post back if you have trouble ( I may have
                            missed
                            something. <G>).
                            >
                            >There are a lot of alternatives to mine and Bob's suggestion. In fact,
                            >if I
                            >was designing this class myself I would totally encapsulate the map
                            >inside
                            >the class and main would only get to it via functions. Depending on
                            >what it
                            >would be for something like (untested code)
                            >
                            >class SearchText
                            >{
                            >public:
                            > SearchText( const std::string& FileName );
                            > int Value( const std::string& key ) const;
                            > int CountWords();
                            >private:
                            > std::map<std::s tring, intData_;
                            >
                            >}
                            >
                            >SearchText::Se archText( const std::string& FileName )
                            >{
                            > // Open file and load Data_
                            >
                            >}
                            >
                            >int Value( const std::string& Key ) const
                            >{
                            > if ( Data_.find( Key ) != Data_.end() )
                            > return Data_[Key];
                            > else
                            > return 0;
                            >
                            >}
                            >
                            >int CountWords()
                            >{
                            > // Return whatever it is this is trying to count
                            >
                            >}
                            >
                            >I am a strong believe in data encapsulation in classes, and try to
                            >always
                            >prevent giving points or references to my internal classes data.
                            >Anything
                            >you need the map for in mian you can encapsulate. Even encapsulate
                            >operator[] if you wish.
                            >
                            >int SearchText::ope rator[]( const std::string& Key )
                            >{
                            > return Value( Key );
                            >
                            >}- Tekst uit oorspronkelijk bericht niet weergeven -
                            >
                            >- Tekst uit oorspronkelijk bericht weergeven -- Tekst uit oorspronkelijk
                            >bericht niet weergeven -
                            >
                            >- Tekst uit oorspronkelijk bericht weergeven -
                            >
                            Thanks a lot you guys for all the reactions!
                            >
                            The reason why I did not want to copy the entire map, was because I'm
                            going to use it for counting the words in
                            >>
                            which is a 3,3 mb text file. ;)
                            >
                            However, as Jim Langston already mentioned (and maybe you too Kai-Uwe
                            Bux, I'm going to study your examples more closely), I can encapsulate
                            this map into the SearchText class, since the map and the file are
                            related and there is no need to seperate them. Any possible new file
                            will need a new instance of SearchText anyway.
                            >
                            Thanks a lot though. I never worked via this principle of newsgroups,
                            but I'm going to have a look here more often!
                            >
                            For those of you interested: I need this for the first assignment of a
                            Natural Language Processing course (at University of Amsterdam) and
                            next assignments will build on this one, so I wanted to make this
                            stuff so generic as possible. Some of you now might say: Use Python!
                            But I really want to learn C++ (and I would have to learn Python
                            too...) and the only way to do this is by programming :)
                            >
                            I can understand not wanting to copy the map being 3.3 megabytes. Be
                            aware, however, that if you copy your class, the map will get copied also.
                            So just make sure you pass your class by reference than by value. One way
                            to ensure this is to disable copying of your class. The normal way to do
                            this is to create a copy constructor ( and assignment operator) and make
                            them private to the class. That way if you accidently write some code
                            that would create a copy of the class, it won't compile and you will
                            realize it.
                            >
                            For the SearchText class that would be:
                            >
                            class SearchText
                            {
                            public:
                            // ...
                            private:
                            >
                            // Disable copy and assignment by making private.
                            SearchText( SearchText const&) {}
                            SearchText& operator=( SearchText const&) {}
                            }
                            >
                            Just empty copy constructor and assignment operator's private to the
                            class.
                            >
                            Just a note. I noticed in that code that in operator= I don't have a return
                            statement. I looked in my own code where I'm doing this same thing and also
                            don't have a return statement. I don't know if that's a compiler flaw not
                            catching it, or the standard allows it. I think, however, that
                            SearchText& opeator=( SearchText const& ) { return this; }
                            would be more correct, even though it will never be called.
                            One more question though. Why are all you guys constantly typing
                            'std::something ', instead of just typing 'using namespace std' one
                            time at the top of each file?

                            Comment

                            • Victor Bazarov

                              #15
                              Re: map (associative array) loses values?

                              jeroenvlek@gmai l.com wrote:
                              [... excessive quoting removed ...]
                              >
                              One more question though. Why are all you guys constantly typing
                              'std::something ', instead of just typing 'using namespace std' one
                              time at the top of each file?


                              V
                              --
                              Please remove capital 'A's when replying by e-mail
                              I do not respond to top-posted replies, please don't ask


                              Comment

                              Working...