Thread: strcspn & strlen

  1. #1
    Registered User
    Join Date
    Oct 2001
    Posts
    12

    strcspn & strlen

    Ok, I have searched the archives and cannot find an answer to my question, so ... I am tokenizing strings by the delimiter ':' and cannot seem
    to assign and index value from the output of the strcspn function. Anyone help?

    Also having trouble comparing a strlen output to an integer value, any clue?


    Code:
    #include <iostream>
    #include <cstring>             //for strcpy(), strcat() etc.
    using namespace std;
    ////////////////////////////////////////////////////////////////
    class String                    //user-defined string type
    {
    	protected:
           enum { SZ = 80 };          //size of all String objects
    	   char str[SZ];              //holds a C-string
    	public:
           String()			          //no-arg constructor
                  { str[0] = '\0'; }
    	   String( char s[] )         //1-arg constructor
    	       { strcpy(str, s); }    //   convert C-string to String
    	   void display() const       //display the String
    	       { cout << str; }
    	   operator char*()           //conversion operator
    	       { return str; }        //convert String to C-string
    	   String operator + (String s1);
    	   bool operator == (String s1);
    	   bool operator > (String s1);
    	   bool operator < (String s1);
    	   bool operator != (String s1);
    	   bool operator >= (String s1);
    	   bool operator <= (String s1);
    };
    String String::operator + (String s1)
    {
    	strcat(str, s1);
    	return s1;
    }
    bool String::operator == (String s1)
    {
    	 return (strcmp(str, s1)==0 ) ? true : false; 
    }
    bool String::operator > (String s1)
    {
    	 return (strcmp(str, s1) > 0 ) ? true : false; 
    }
    bool String::operator < (String s1)
    {
    	 return (strcmp(str, s1) < 0 ) ? true : false; 		
    }
    bool String::operator != (String s1)
    {
    	 return (strcmp(str, s1) != 0 ) ? true : false; 				
    }
    bool String::operator >= (String s1)
    {
    	 return (strcmp(str, s1) >= 0 ) ? true : false; 
    }
    bool String::operator <= (String s1)
    {
    	 return (strcmp(str, s1) <= 0 ) ? true : false; 
    }
    class StringTokenizer : public String
    {
    	private:
    		int index;
    		char delimiter;
    	public:
    		StringTokenizer(String s1, char d) 
    			{	
    				d = ' ';
    			}
    		int countToken()
    			{	
    				int temp;
    				temp = strcspn( str , ":" ); //<<<<---- Problems here
    				temp++;     //account for the end of the string
    				return temp;
    			}
    		bool hasMoreToken()
    			{
    				if (index < strlen(str))   //<<<----- And Here!
    					return true;
    				else 
    					return false;
    			}
    		String nextToken()
    			{
    				str.erase(0, index);		//erase everything from front of string to index
    				int end = str.find(':');	//find the end of the token
    				int null = str.find('\0');  //find the end of the string
    				str.erase(end, null - 1);	//erase everything from end of token to 1 before null
    			}
    };
    Already spent too many hours trying to figure it out.. Thanks!

    Andrew

  2. #2
    Registered User
    Join Date
    Dec 2001
    Posts
    479
    well we cant figure it out either if u dont give uss the entire code
    or at least tell uss how erase() and find() work??!

  3. #3
    Registered User
    Join Date
    Oct 2001
    Posts
    12
    Code:
    void main(void)
    {
    	String s("dunc0035:!:5701:500::/shome/dunc0035:/bin/ksh");
        StringTokenizer tokens( s, ':' );
    }
    Heres the rest of the code... It won't help you...

    .find(), erase, replace and insert are string objects, how are they relevent to my problems??

    Originally posted by pode
    well we cant figure it out either if u dont give uss the entire code
    or at least tell uss how erase() and find() work??!

  4. #4
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    I do not see how this comiles at all. str in your String class, and thus your decendant(?!) StringTokenizer is a char[]. I don't see how .find() works here. strcspn() returns the number of characters before ":" not the number of ":"'s The constructor to StringTokenizer ingores all of it's paramiters, and in fact set's one of them to space for no earthly reason, then leaves str as the empty string from the default ctor of String. index is set to just random garbage. NextToken blows away all other tokens (if find and erase work the same way as std::string) and then does not even bother with returning anything.

    The only thing I can help you with, without re-writing the whole thing, is strlen. strlen returns a size_t, usually unsigned, make index a size_t or cast away the warning, but that is by far the least of your problems.

  5. #5
    Registered User
    Join Date
    Jan 2003
    Posts
    311
    That was poorly written, so heck, just use this.

    Code:
    #include<deque>
    #include<string>
    #include<iostream>
    
    class tokenizer {
    	std::deque<std::string> tokens;
    	std::string delm;
    	typedef std::string::size_type index_t;
    public:
    	tokenizer(const std::string &d=" ") : delm(d) {}
    	void parse(const std::string &);
    	const std::string & top() const {return tokens.front();}
    	void pop() { tokens.pop_front(); }
    	bool empty() const { return tokens.empty();}
    };
    
    void tokenizer::parse(const std::string &s) {
    	index_t start=0;
            index_t end;
    	do {
    		end=s.find_first_of(delm,start);
    		tokens.push_back(s.substr(start,end-start));
    		start = end+1;
    	} while(end != std::string::npos);
    }
    
    int main(int argc, char *argv[]) {
    	tokenizer t(":");
    	if(argc==1) {
    		t.parse("dunc0035:!:5701:500::/shome/dunc0035:/bin/ksh");
    	} else {
    		for(int i=1;i<argc;++i) t.parse(argv[i]);
    	}
    	while(!t.empty()) {
    		std::cout <<'"'<< t.top() <<'"'<< std::endl;
    		t.pop();
    	}
    	return 0;
    }

  6. #6
    Registered User Cela's Avatar
    Join Date
    Jan 2003
    Posts
    362
    I had this same problem one time, I ended up having to write my own strspn and strcspn to get it to work right since those two functions don't take a position marker. Sorry, it's in C, but you can borrow whatever parts you want :-)
    Code:
    const char *bad_char = " ";
    
    int strfind(char c, const char *str)
    {
      while (*str != '\0')
      {
        if (*str++ == c)
        {
          return 1;
        }
      }
    
      return 0;
    }
    
    size_t strnspn(const char *s, const char *find, size_t begin)
    {
      size_t first = begin;
    
      while (s[first] != '\0' && strfind(s[first], find))
      {
        first++;
      }
    
      return first;
    }
    
    size_t strcnspn(const char *s, const char *find, size_t begin)
    {
      size_t first = begin;
    
      while (s[first] != '\0' && !strfind(s[first], find))
      {
        first++;
      }
    
      return first;
    }
    
    char *substr(const char *s, size_t begin, size_t end)
    {
      char *p = 0;
    
      p = malloc(end - begin+1);
    
      *p = '\0';
    
      strncat(p, s + begin, end - begin);
    
      return p;
    }
    
    char *next_token(const char *s, size_t *pos)
    {
      size_t begin = strnspn(s, bad_char, *pos);
      size_t end = strcnspn(s, bad_char, begin);
    
      *pos = end;
    
      if (s[begin] == '\0')
      {
        return 0;
      }
      else
      {
        return substr(s, begin, end);
      }
    }
    *Cela*

  7. #7
    Registered User
    Join Date
    Oct 2001
    Posts
    12
    Thanks Cela!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strlen help
    By stewie1986 in forum C Programming
    Replies: 10
    Last Post: 12-04-2007, 12:15 PM
  2. strlen in expressions
    By justforthis1 in forum C++ Programming
    Replies: 4
    Last Post: 10-24-2006, 10:28 AM
  3. strlen()
    By exoeight in forum C Programming
    Replies: 9
    Last Post: 04-01-2005, 10:18 AM
  4. Just say NO to strlen.
    By anonytmouse in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 02-11-2005, 01:34 PM
  5. Why O why, strlen?
    By Sebastiani in forum C Programming
    Replies: 11
    Last Post: 08-24-2001, 01:41 PM