Thread: Exception with ::tolower

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    385

    Exception with ::tolower

    I am trying to read a .txt file and search for a number that is inside two brackets like this (Inside "Numb[?]")

    What I also is doing is to transform all characters to lowercase and this I do inside the while loop. When I do this my program throws an exeption when running.
    If I dont use a while loop and would manually put a string to the string Line then this will work.
    Why could this happen when I use a while loop.



    Code:
    #include <ctype.h>
    
    std::string Line;
    string stringToFind1 = "Numb[";
    
    while( getline(fin1, Line, '\n')  )
    
    {
    std::transform(Line.begin(), Line.end(), Line.begin(), ::tolower);
    string::size_type startPos = Line.find(stringToFind1);
    startPos += stringToFind1.length(); 
    string::size_type endPos = Line.find("]", startPos); 
    string Number = Line.substr(startPos, endPos - startPos); 
     	
    	if( Line.find(stringToFind1) != string::npos )
    	{
    		fout1 << Number;
    	}
    				
    }

  2. #2
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    If it's all lowercase, how will you find "Numb["?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    yes you are right. It could also be like this. So in the above case I shouldn&#180;t find it but in this case I will then but strange is that this while loop throws an exception. I cant really get it what it is.
    Even if I will // the first line in the while loop that contains std::transform, I will get the exception.

    Code:
    [string strigToFind1 = "numb[";

  4. #4
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Quote Originally Posted by Coding View Post
    yes you are right. It could also be like this. So in the above case I shouldn´t find it but in this case I will then but strange is that this while loop throws an exception. I cant really get it what it is.
    Even if I will // the first line in the while loop that contains std::transform, I will get the exception.
    Doesn't commenting out the transform further the case that the exception is elsewhere? Such as doing math on an error condition?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Do all your lines have numb[ in them? Otherwise startPos is out of range.

  6. #6
    Registered User
    Join Date
    Sep 2004
    Location
    California
    Posts
    3,268
    Check to make sure the result of your find() call isn't string::npos, don't just assume that the result is valid.

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    >> Check to make sure the result of your find() call isn't string::npos, don't just assume that the result is valid.

    I think my problem is somewhere here. If my .txt file contains only lines with text without any blank lines beween. Then the code works but if I change so there is a blank line in the text file then I get the exception.

    I thought this code took this into considiration but perheps I am wrong ?
    Code:
    if( Line.find(stringToFind1) != string::npos )
    	{
    		fout1 << Number;
    	}

  8. #8
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Playing it in my head, I see something like this:
    Code:
    while( getline(fin1, Line, '\n')  )
    
    {
    std::transform(Line.begin(), Line.end(), Line.begin(), ::tolower);
    string::size_type startPos = Line.find(stringToFind1); 
    startPos += stringToFind1.length(); // BANG!!!!
    string::size_type endPos = Line.find("]", startPos); 
    string Number = Line.substr(startPos, endPos - startPos); 
     	
    	if( Line.find(stringToFind1) != string::npos ) // safety check
    	{
    		fout1 << Number;
    	}
    				
    }
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  9. #9
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    Yes, you are right. I changed the code to this to make sure the string is not emty.
    Thanks for your help...

    Code:
    while( getline(fin1, Line, '\n')  )
    {
       if( Line != "")
       {
       
       std::transform(Line.begin(), Line.end(), Line.begin(), ::tolower);
       string::size_type startPos = Line.find(stringToFind1); 
       startPos += stringToFind1.length(); 
       string::size_type endPos = Line.find("]", startPos); 
       string Number = Line.substr(startPos, endPos - startPos); 
     	
    	if( Line.find(stringToFind1) != string::npos ) // safety check
    	{
    		fout1 << Number;
    	}
    
       }				
    }

  10. #10
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Dave_Sinkula View Post
    Playing it in my head, I see something like this:
    Code:
    while( getline(fin1, Line, '\n')  )
    
    {
    std::transform(Line.begin(), Line.end(), Line.begin(), ::tolower);
    string::size_type startPos = Line.find(stringToFind1); 
    startPos += stringToFind1.length(); // BANG!!!!
    string::size_type endPos = Line.find("]", startPos); 
    string Number = Line.substr(startPos, endPos - startPos); 
     	
    	if( Line.find(stringToFind1) != string::npos ) // safety check
    	{
    		fout1 << Number;
    	}
    				
    }
    Actually, I think the BANG might belong two lines lower. (I know C requires implementations to handle unsigned overflow as wraparound without a signal, but maybe C++ is different.) But the point is, you need to stop just as soon as you find npos, which is right there on line 2.

  11. #11
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    I am not really sure if I follow. To find npos, I think meens to find the end of the string ?

    I dont think my solution is the right approach even that it works. I am not sure wich line is, line 2.
    Is it something I am doing wrong in the code that it cant handle blank lines.
    Last edited by Coding; 03-16-2008 at 02:21 PM.

  12. #12
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    My play code:
    Code:
    #include <iostream>
    #include <fstream>
    #include <string>
    
    int main()
    {
       std::ifstream file("file.txt");
       const std::string stringToFind1 = "Numb[";
       std::string Line;
       while ( std::getline(file, Line) )
       {
          std::string::size_type startPos = Line.find(stringToFind1);
          if ( startPos != std::string::npos )
          {
             startPos += stringToFind1.length(); 
             std::string::size_type endPos = Line.find("]", startPos); 
             if ( endPos != std::string::npos )
             {
                std::string Number = Line.substr(startPos, endPos - startPos); 
                if ( Line.find(stringToFind1) != std::string::npos )
                {
                   std::cout << Number << '\n';
                }
             }
          }
       }
       return 0;
    }
    
    /* file.txt
    df dNumb[123]df
    
    asdf asd fa Numb[456]  dv df asdf 
    
    Numb[456]  dv df asdf 
    
    asdf asd fa Numb[456]
    asdf asd fa Numb[456 5654a ]
    asdf asd fa Numb[456
    
    */
    
    /* my output
    123
    456
    456
    456
    456 5654a 
    */
    The general idea: make sure you've found something before you operate on what you've found.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  13. #13
    Registered User
    Join Date
    Dec 2007
    Posts
    385
    Thanks... I think I undestand now.
    The magic thing is to check that this to make sure you are handling the correct string.
    This worked great.

    Code:
    if ( startPos != std::string::npos )
    if ( endPos != std::string::npos )

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Exception handling in a large project
    By EVOEx in forum C++ Programming
    Replies: 7
    Last Post: 01-25-2009, 07:33 AM
  2. exception handling
    By coletek in forum C++ Programming
    Replies: 2
    Last Post: 01-12-2009, 05:28 PM
  3. Handle C++ exception and structured exception together
    By George2 in forum C++ Programming
    Replies: 2
    Last Post: 01-24-2008, 09:21 PM
  4. Signal and exception handling
    By nts in forum C++ Programming
    Replies: 23
    Last Post: 11-15-2007, 02:36 PM
  5. Problem with the exception class in MINGW
    By indigo0086 in forum C++ Programming
    Replies: 6
    Last Post: 01-20-2007, 01:12 PM