Thread: Help with code.

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    127

    Help with code.

    int main( int argc, char *argv[] )
    {

    ==> This function has over 60 lines.
    You need to split it into smaller functions


    Everytime I try to split it up I just cause errors (it compiles but locks up when I run it through the test system so I think I'm doing something wrong). If anyone could have a look at it I would appreciate it.

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    #include "bintree.h"
    
    using namespace std;
    
    class word
    {
       public:
    
       word();
       int getCount() { return count; }
       const char *getWord() const { return sWord.c_str(); }
    
       void setWord( const char* word )
       {
          sWord = word;
          buildPrintString();
       }
    
       void setCount( int n )
       {
          count = n;
          buildPrintString();
       }
    
       bool operator== (const word& wrd ) const
       {
    
          return !sWord.compare( wrd.getWord() );
       }
    
       bool operator< (word &wrd ) const
       {
          return ( sWord.compare( wrd.getWord() ) < 0 );
       }
    
       const char *toString() const
       {
          return printStr.c_str();
       }
    
       private:
       string sWord;
       string printStr;
       int count;
    
       void buildPrintString()
       {
          char count[10];
    
          sprintf( count, "%d", this->count );
          printStr = "  ";
          if ( this->count < 9 )
             printStr += " ";
          printStr += count;
          printStr += "  | " + sWord;
       }
    };
    
    word::word()
    
    {
       count = 0;
    }
    
    int main( int argc, char *argv[] )
    {
       if ( argc < 2 )
       {
          cout<<"ERROR - Incorrect number of arguments"<endl;
          cout<<"Syntax : wordcount filename"<<endl<<endl;
          return 0;
       }
    
       ifstream file( argv[1] );
       if ( !file.is_open() )
       {
          cout<<"ERROR - Unable to access "<<argv[1]<<endl;
          return 0;
       }
    
       int totalWords = 0, uniqueWords = 0;
       bintree<word> tree;
    
       while ( !file.eof() )
       {
          char buff[256];
    
          file.getline( buff, 226 );
    
          char *newword = strtok( buff, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
    
          while ( newword )
          {
             // strip any word of double quotes
             string strWord = newword;
             size_t found;
    
             found = strWord.find_first_of("\"");
             while ( found != string::npos )
             {
                strWord.erase( found, 1 );
                found = strWord.find_first_of( "\"", found+1 );
             }
    
             if ( strWord.length() < 1 )
             {
                newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
                continue;
             }
    
             word temp;
    
             temp.setWord( strWord.c_str() );
    
             word *find = tree.find( temp );
    
             // Not in tree, means first occurence of the word
             if ( !find )
             {
                temp.setCount( 1 );
                tree.insert( temp );
                uniqueWords++;
             }
             else
             {
                find->setCount( find->getCount() + 1 );
             }
    
             totalWords++;
    
             newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
          }
       }
    
       cout<<"\nfilename : "<<argv[1]<<endl<<endl;
    
       cout<<"COUNT | WORD"<<endl;
       cout<<"------+------"<<endl;
       tree.print();
    
       cout<<endl;
    
       cout<<"Number of unique words in "<<argv[1]<<" is "<<uniqueWords<<endl;
       cout<<"Total number of words in "<<argv[1]<<" is  "<<totalWords<<endl;
    
       return 0;
    }
    This is my attempt, it compiles but when I go to run it it just locks up and doesn't run.

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    #include "bintree.h"
    
    using namespace std;
    
    int main(int, char**);
    void checkWords();
    void printWords();
    
    class word
    {
       public:
    
       word();
       int getCount() { return count; }
       const char *getWord() const { return sWord.c_str(); }
    
       void setWord( const char* word )
       {
          sWord = word;
          buildPrintString();
       }
    
       void setCount( int n )
       {
          count = n;
          buildPrintString();
       }
    
       bool operator== (const word& wrd ) const
       {
    
          return !sWord.compare( wrd.getWord() );
       }
    
       bool operator< (word &wrd ) const
       {
          return ( sWord.compare( wrd.getWord() ) < 0 );
       }
    
       const char *toString() const
       {
          return printStr.c_str();
       }
    
       private:
       string sWord;
       string printStr;
       int count;
    
       void buildPrintString()
       {
          char count[10];
    
          sprintf( count, "%d", this->count );
          printStr = "  ";
          if ( this->count < 9 )
             printStr += " ";
          printStr += count;
          printStr += "  | " + sWord;
       }
    };
    
    word::word()
    {
       count = 0;
    }
    
    int main( int argc, char *argv[] )
    {
       if ( argc < 2 )
       {
          cout<<"ERROR - Incorrect number of arguments"<<endl;
          cout<<"Syntax : wordcount filename"<<endl<<endl;
          return 0;
       }
    
       ifstream file( argv[1] );
       if ( !file.is_open() )
       {
          cout<<"ERROR - Unable to access "<<argv[1]<<endl;
          return 0;
       }
    
       checkWords();
    
       return 0;
    }
    
    void checkWords()
    {
       int totalWords = 0, uniqueWords = 0;
       char *argv[1];
       bintree<word> tree;
       ifstream file( argv[1] );
    
       while ( !file.eof() )
       {
          char buff[256];
    
          file.getline( buff, 226 );
    
          char *newword = strtok( buff, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
    
          while ( newword )
          {
             // strip any word of double quotes
             string strWord = newword;
             size_t found;
    
             found = strWord.find_first_of("\"");
             while ( found != string::npos )
             {
                strWord.erase( found, 1 );
                found = strWord.find_first_of( "\"", found+1 );
             }
    
             if ( strWord.length() < 1 )
             {
                newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
                continue;
             }
    
             word temp;
    
             temp.setWord( strWord.c_str() );
    
             word *find = tree.find( temp );
    
             // Not in tree, means first occurence of the word
             if ( !find )
             {
                temp.setCount( 1 );
                tree.insert( temp );
                uniqueWords++;
             }
             else
             {
                find->setCount( find->getCount() + 1 );
             }
    
             totalWords++;
             newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
          }
       }
    
          printWords();
    }
    
    void printWords()
    {
       int totalWords;
       int uniqueWords;
       char *argv[1];
       bintree<word> tree;
    
       cout<<endl<<"filename : "<<argv[1]<<endl<<endl;
    
       cout<<"COUNT | WORD"<<endl;
       cout<<"------+------"<<endl;
       tree.print();
    
       cout<<endl;
    
       cout<<"Number of unique words in "<<argv[1]<<" is "<<uniqueWords<<endl;
       cout<<"Total number of words in "<<argv[1]<<" is  "<<totalWords<<endl;
    }

  2. #2
    Registered User
    Join Date
    Sep 2001
    Posts
    4,912
    One thing about splitting a function up is that you need to isolate each function appropriately. Let's look at an example in your last function:
    Code:
    char *argv[1];
    It looks to me like you broke the code up into pieces without redesigning your approach, and then realized certain variables were no longer in scope - so you redeclared them again. In this case you ended up with a different pointer than what you originally had, didn't initialize it to anything, and then tried to dereference it here:
    Code:
    cout<<endl<<"filename : "<<argv[1]<<endl<<endl;
    And you ended up with a seg fault, and your program crashed.

    To fix this, you need to make sure that data used by every function is made global (global variables should be avoided, where you can - too many is bad coding style, and actually illegal in some countries). Data that is less common, but still shared between 2 functions can maybe be passed as a parameter.

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    I'm not allowed to use global variables so how else could I do this?

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Pass the relevant variable(s) to the function?

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #5
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    I'm not sure how to do that in this case sorry.

  6. #6
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    So the below code now runs, the problem is that where it was outputting and calculating originally it no longer does. Can anyone see why/help me with why please?

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    #include "bintree.h"
    
    using namespace std;
    
    int main(int, char**);
    void checkWords(int, char**);
    void printWords(int, char**);
    
    class word
    {
       public:
    
       word();
       int getCount() { return count; }
       const char *getWord() const { return sWord.c_str(); }
    
       void setWord( const char* word )
       {
          sWord = word;
          buildPrintString();
       }
    
       void setCount( int n )
       {
          count = n;
          buildPrintString();
       }
    
       bool operator== (const word& wrd ) const
       {
    
          return !sWord.compare( wrd.getWord() );
       }
    
       bool operator< (word &wrd ) const
       {
          return ( sWord.compare( wrd.getWord() ) < 0 );
       }
    
       const char *toString() const
       {
          return printStr.c_str();
       }
    
       private:
       string sWord;
       string printStr;
       int count;
    
       void buildPrintString()
       {
          char count[10];
    
          sprintf( count, "%d", this->count );
          printStr = "  ";
          if ( this->count < 9 )
             printStr += " ";
          printStr += count;
          printStr += "  | " + sWord;
       }
    };
    
    word::word()
    {
       count = 0;
    }
    
    int main( int argc, char *argv[] )
    {
       if ( argc < 2 )
       {
          cout<<"ERROR - Incorrect number of arguments"<<endl;
          cout<<"Syntax : wordcount filename"<<endl<<endl;
          return 0;
       }
    
       ifstream file( argv[1] );
       if ( !file.is_open() )
       {
          cout<<"ERROR - Unable to access "<<argv[1]<<endl;
          return 0;
       }
    
       checkWords(argc, argv);
       printWords(argc, argv);
    
       return 0;
    }
    
    void checkWords( int argc, char *argv[] )
    {
       int totalWords = 0, uniqueWords = 0;
       bintree<word> tree;
       ifstream file( argv[1] );
    
       while ( !file.eof() )
       {
          char buff[256];
    
          file.getline( buff, 226 );
    
          char *newword = strtok( buff, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
    
          while ( newword )
          {
             // strip any word of double quotes
             string strWord = newword;
             size_t found;
    
             found = strWord.find_first_of("\"");
             while ( found != string::npos )
             {
                strWord.erase( found, 1 );
                found = strWord.find_first_of( "\"", found+1 );
             }
    
             if ( strWord.length() < 1 )
             {
                newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
                continue;
             }
    
             word temp;
    
             temp.setWord( strWord.c_str() );
    
             word *find = tree.find( temp );
    
             // Not in tree, means first occurence of the word
             if ( !find )
             {
                temp.setCount( 1 );
                tree.insert( temp );
                uniqueWords++;
             }
             else
             {
                find->setCount( find->getCount() + 1 );
             }
    
             totalWords++;
             newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
          }
       }
    }
    
    void printWords( int argc, char *argv[] )
    {
       int totalWords;
       int uniqueWords;
       bintree<word> tree;
    
       cout<<endl<<"filename : "<<argv[1]<<endl<<endl;
    
       cout<<"COUNT | WORD"<<endl;
       cout<<"------+------"<<endl;
       tree.print();
    
       cout<<endl;
    
       cout<<"Number of unique words in "<<argv[1]<<" is "<<uniqueWords<<endl;
       cout<<"Total number of words in "<<argv[1]<<" is  "<<totalWords<<endl;
    }

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    So if you create a brand new tree inside the printWords function, why do you expect it to magically contain all the information from the checkWords function?

  8. #8
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    Ok I get that, but how do I call uniqueWords, totalWords and tree inside the printWords from checkWords?

  9. #9
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    You have to pass them in and out.

  10. #10
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    But how? I'm sorry it's been a long day and I'm not sure what I'm doing.

  11. #11
    Registered User
    Join Date
    Aug 2006
    Posts
    127
    I've tried as below but get the following compile errors:

    main3.cpp:11: error: ISO C++ forbids declaration of 'parameter' with no type
    main3.cpp: In function 'void checkWords(int, char**)':
    main3.cpp:149: error: cannot convert 'bintree<word>' to 'int' for argument '5' to 'void printWords(int, char**, int, int, int)'

    Code:
    #include <iostream>
    #include <string>
    #include <fstream>
    
    #include "bintree.h"
    
    using namespace std;
    
    int main(int, char**);
    void checkWords(int, char**);
    void printWords(int, char**, int, int, const);
    
    class word
    {
       public:
    
       word();
       int getCount() { return count; }
       const char *getWord() const { return sWord.c_str(); }
    
       void setWord( const char* word )
       {
          sWord = word;
          buildPrintString();
       }
    
       void setCount( int n )
       {
          count = n;
          buildPrintString();
       }
    
       bool operator== (const word& wrd ) const
       {
    
          return !sWord.compare( wrd.getWord() );
       }
    
       bool operator< (word &wrd ) const
       {
          return ( sWord.compare( wrd.getWord() ) < 0 );
       }
    
       const char *toString() const
       {
          return printStr.c_str();
       }
    
       private:
       string sWord;
       string printStr;
       int count;
    
       void buildPrintString()
       {
          char count[10];
    
          sprintf( count, "%d", this->count );
          printStr = "  ";
          if ( this->count < 9 )
             printStr += " ";
          printStr += count;
          printStr += "  | " + sWord;
       }
    };
    
    word::word()
    {
       count = 0;
    }
    
    int main( int argc, char *argv[] )
    {
       if ( argc < 2 )
       {
          cout<<"ERROR - Incorrect number of arguments"<<endl;
          cout<<"Syntax : wordcount filename"<<endl<<endl;
          return 0;
       }
    
       ifstream file( argv[1] );
       if ( !file.is_open() )
       {
          cout<<"ERROR - Unable to access "<<argv[1]<<endl;
          return 0;
       }
    
       checkWords(argc, argv);
    
       return 0;
    }
    
    void checkWords( int argc, char *argv[] )
    {
       int totalWords = 0, uniqueWords = 0;
       bintree<word> tree;
       ifstream file( argv[1] );
    
       while ( !file.eof() )
       {
          char buff[256];
    
          file.getline( buff, 226 );
    
          char *newword = strtok( buff, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
    
          while ( newword )
          {
             // strip any word of double quotes
             string strWord = newword;
             size_t found;
    
             found = strWord.find_first_of("\"");
             while ( found != string::npos )
             {
                strWord.erase( found, 1 );
                found = strWord.find_first_of( "\"", found+1 );
             }
    
             if ( strWord.length() < 1 )
             {
                newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
                continue;
             }
    
             word temp;
    
             temp.setWord( strWord.c_str() );
    
             word *find = tree.find( temp );
    
             // Not in tree, means first occurence of the word
             if ( !find )
             {
                temp.setCount( 1 );
                tree.insert( temp );
                uniqueWords++;
             }
             else
             {
                find->setCount( find->getCount() + 1 );
             }
    
             totalWords++;
             newword = strtok( NULL, " \t\r\n,;:”~!#%^*()=+[]{}\\|<>?/." );
          }
       }
    
       printWords(argc, argv, totalWords, uniqueWords, tree);
    
    }
    
    void printWords( int argc, char *argv[], int totalWords, int uniqueWords, const 
    bintree<word> tree )
    {
    //   int totalWords;
    //   int uniqueWords;
    //   bintree<word> tree;
    
       cout<<endl<<"filename : "<<argv[1]<<endl<<endl;
    
       cout<<"COUNT | WORD"<<endl;
       cout<<"------+------"<<endl;
       tree.print();
    
       cout<<endl;
    
       cout<<"Number of unique words in "<<argv[1]<<" is "<<uniqueWords<<endl;
       cout<<"Total number of words in "<<argv[1]<<" is  "<<totalWords<<endl;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Extended ASCII Characters in an RTF Control
    By JustMax in forum C Programming
    Replies: 18
    Last Post: 04-03-2009, 08:20 PM
  2. Enforcing Machine Code Restrictions?
    By SMurf in forum Tech Board
    Replies: 21
    Last Post: 03-30-2009, 07:34 AM
  3. Obfuscated Code Contest
    By Stack Overflow in forum Contests Board
    Replies: 51
    Last Post: 01-21-2005, 04:17 PM
  4. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM
  5. Replies: 0
    Last Post: 02-21-2002, 06:05 PM