Thread: String issues

  1. #1
    Registered User
    Join Date
    Nov 2003
    Posts
    26

    String issues

    Hey,

    I am writing a palindrome app for a class. I'm having a problem though using size() or length() for the string lengths. I keep getting a typecast error but I am almost sure I am writing it correctly (I have searched the boards, read the FAQ, and looked in my book). I see multiple examples written this way:

    Code:
    #include <iostream>
    #include <string>
    #include <cctype>
    
    using namespace std;
    
    int main() {
    	string s;
    	int x;
    
    	cout << "Enter a string:" << endl;
    	cin >> s;
    	x = s.size();
    	cout << endl << "The string " << s << " is " << x << " characters long." << endl;
    	return 0;
    }
    On compile I get the following error:

    Code:
    c:\Documents and Settings\Josh\My Documents\Visual Studio Projects\strings\strings\strings.cpp(13) : warning C4267: '=' : conversion from 'size_t' to 'int', possible loss of data
    Im using Visual Studio 7.0. I know it's just a warning but is there anyway to make it right?

    Thanks,
    Joshua Norton
    Regards,
    ~Joshua Norton

  2. #2
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Just change your declaration to:

    size_t x;
    Code:
    #include <cmath>
    #include <complex>
    bool euler_flip(bool value)
    {
        return std::pow
        (
            std::complex<float>(std::exp(1.0)), 
            std::complex<float>(0, 1) 
            * std::complex<float>(std::atan(1.0)
            *(1 << (value + 2)))
        ).real() < 0;
    }

  3. #3
    Registered User
    Join Date
    Nov 2003
    Posts
    26

    ...

    I also get
    "signed unsigned mismatch" when comparing the size to an int in a for loop.

    Not sure what a size_t is. Im guessing it's a type created in the string header or something? Is it just like an int or what?

    Thanks,
    Joshua Norton
    Regards,
    ~Joshua Norton

  4. #4
    Registered User
    Join Date
    Nov 2003
    Posts
    26

    ...

    Certainly fixed all the errors though. I will search for it and try and find info. Thanks for the help Sebastiani.

    ~Joshua Norton
    Regards,
    ~Joshua Norton

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    12

    Re: ...

    Originally posted by Josh Norton
    I also get
    "signed unsigned mismatch" when comparing the size to an int in a for loop.

    Not sure what a size_t is. Im guessing it's a type created in the string header or something? Is it just like an int or what?

    Thanks,
    Joshua Norton
    Its defined in stddef.h and few other files. Its defined as

    Code:
    typedef unsigned int size_t;
    Life is a piece of chocolates

  6. #6
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >typedef unsigned int size_t;
    Not necessarily. The standard only specifies that size_t is an unsigned integer type of the result of the sizeof operator. That doesn't mean that it actually is unsigned int. If it were then we wouldn't need a typedef, would we?
    My best code is written with the delete key.

  7. #7
    Registered User
    Join Date
    Nov 2003
    Posts
    26

    ...

    I know comparing a syze_t type to an int in my for loop caused a seg fault. I guess since size_t was unsigned and being compared to a negative value(or so I assumed)? I changed "i" to an int and it was fine. I can't get rid of the warning though. I'm guessing you could cast it somehow and make it right?

    ~Joshua Norton
    Last edited by Josh Norton; 03-07-2004 at 07:40 PM.
    Regards,
    ~Joshua Norton

  8. #8
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I guess since size_t was unsigned and being compared to a negative value
    That would be a good guess.

    >I can't get rid of the warning though.
    Post the loop in question, the declarations of variables involved, and the warning you get.
    My best code is written with the delete key.

  9. #9
    Registered User
    Join Date
    Nov 2003
    Posts
    26

    ....

    I'll just post it all... It's not an error. Just a warning. It reads:

    Code:
    lab7.cpp(93) : warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data
    The loop I had the comparison in is near the bottom. In the palindromEval() function. I commented a note above it.

    Code:
    //name:  Lab 7
    //author:  Joshua Norton
    //description:  This program is designed to take in a string from the user(punctuation and whitespace are BOTH accepted)
    //				and determine if that string is a palindrome or not.
    
    #include <iostream>
    //cctype is included for the ifpunct() and ifspace() functions
    #include <cctype>
    #include <string>
    
    using namespace std;
    
    string stringStrip(string userString);
    bool palindromeEval(string originalString);
    
    int main(void) {
    	int quit = 0;
    	bool mismatch = false;
    	string userString, originalString;
    
    	//menu loop
    	while(quit != 2) {
    		quit = 0;
    		//menu options
    		cout << "Please choose from the following options:" << endl << endl
    		     << "1) Evaluate a new string to see if it's a plaindrome." << endl
    		     << "2) Quit." << endl << endl;
    	 
    		cin >> quit;
    
    		switch(quit) {
    			case 1:
    				//prompt the user for a string
    				cout << "Please enter the string you would like to evaluate." << endl;
    				//I had some trouble with the getline function.  I guess VS7 leaves a return character in the input buffer
    				//which causes the getline function to exit without ever prompting the user for input.  I found quite a few
    				//posts regarding the subject and the concensous for handling it seemed to be the cin.ignore command
    				cin.ignore();
    				//intake the users string
    				getline(cin, userString);
    				originalString = stringStrip(userString);
    
    				if(palindromeEval(originalString)) {
    					//mismatch true
    					cout << endl << endl << "------------------------------------------------" << endl
    					     << "Sorry, \"" << userString << "\" is not a palindrome." << endl
    						 << "------------------------------------------------" << endl << endl;
    				} else {
    					//mismatch false
    					cout << endl << endl << "------------------------------------------------" << endl
    						 << "\"" <<  userString << "\" is a palindrome!" << endl
    						 << "------------------------------------------------" << endl << endl;
    				}
    				break;
    			case 2:
    				cout << "Quitting..." << endl;
    				break;
    			//validation for the menu
    			default:
    			cout << "You have entered an invalid option." << endl << endl;
    			break;
    		}
    	}
    	return 0;
    }
    //the stringStrip() function removes puncuation and whitespace from the original string then sets it all lowercase.
    string stringStrip(string userString) {
    	string originalString;
    	size_t i, len;
    	len = userString.size();
    
    	//copy only chars that are not whitespace or punctuation
    	for(i = 0; i < len; i++) {
    		if((!isspace(userString[i])) && (!ispunct(userString[i]))) {
    			originalString += userString[i];
    		}
    	}
    	//set string to lowercase
    	for(i = 0; i < originalString.size(); i++) {
    		originalString[i] = tolower(originalString[i]);
    	}
    	return originalString;
    }
    
    //palindromeEval creates a reverse copy of the formatted string and compares the 2 strings to see if they are a palindrome
    bool palindromeEval(string originalString) {
    	bool mismatch = false;
    	string reverseString;
    	size_t len = originalString.size();
    
                     //This loop right here used to read for(size_t i = len-1...
    	//create a reverse copy of the string
    	for(int i = len-1; i >= 0; i--) {
    		reverseString += originalString[i];
    	}
    
    	//compare the strings to see if they are a palindrome
    	if(originalString == reverseString) {
    		mismatch = false;
    	} else {
    		mismatch = true;
    	}
    	
    	return mismatch;
    }
    Regards,
    ~Joshua Norton

  10. #10
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    You should avoid mixing signed and unsigned variables. It causes more problems than you can imagine. You can modify your loop so that using unsigned quantities will work correctly, or you can make len an int and silence the warning there by casting originalString.size() to int as well.
    My best code is written with the delete key.

  11. #11
    Tha 1 Sick RAT
    Join Date
    Dec 2003
    Posts
    271
    I've just compiled and ran your code through MSVC++ 6.0 and Dev C++.. I didn't get a single warning or error so I guess your problem maybe with your compiler...
    But I'm guessing as prelude said
    Not necessarily. The standard only specifies that size_t is an unsigned integer type of the result of the sizeof operator. That doesn't mean that it actually is unsigned int.
    Seeing as len doesn't really have a type it is warning you that comparing the unsigned integer from possibly two different types could result in information loss (e.g. think what happens when you round off a float number you loose some info.) you want to get rid of it.. the make len an usigned int. It's a warning that can be ignored in this case me thinks but others will disagree.
    A hundred Elephants can knock down the walls of a fortress... One diseased rat can kill everyone inside

  12. #12
    Registered User
    Join Date
    Nov 2003
    Posts
    26

    ....

    ok. When I had 'i' declared size_t and the loop got below zero it was seg faulting since i would roll over(I guess) to the max value for an unsigned int( 4294967295 when I just tried it). I'm not sure how I would format the for statement to get the [0] element of the string without 'i' being decremented past 0. Maybe if I inserted a dummy character into the string at [0] and then accounted for it. Probably easier just to cast 'len' though.
    Regards,
    ~Joshua Norton

  13. #13
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,897
    >I'm not sure how I would format the for statement to get the [0] element of the string without 'i' being decremented past 0.
    The most obvious way would be an unsigned-safe loop followed by a redundant body handling index 0. This avoids a cast and allows you to more obviously handle edge cases:
    Code:
    string::size_type len = originalString.size();
    
    if (len > 1) {
      // For strings with 2 or more characters
      for(string::size_type i = len; i > 1; ) {
        reverseString += originalString[--i];
      }
      reverseString += originalString[0];
    
      if(originalString == reverseString) {
        mismatch = false;
      } else {
        mismatch = true;
      }
    } else {
      // Strings with 1 or 0 characters are always a palindrome
      mismatch = false;
    }
    My best code is written with the delete key.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. char Handling, probably typical newbie stuff
    By Neolyth in forum C Programming
    Replies: 16
    Last Post: 06-21-2009, 04:05 AM
  2. Replies: 8
    Last Post: 04-25-2008, 02:45 PM
  3. String Class
    By BKurosawa in forum C++ Programming
    Replies: 117
    Last Post: 08-09-2007, 01:02 AM
  4. Replies: 4
    Last Post: 03-03-2006, 02:11 AM
  5. Classes inheretance problem...
    By NANO in forum C++ Programming
    Replies: 12
    Last Post: 12-09-2002, 03:23 PM