Thread: Strange Run-time Error

  1. #1
    Registered User
    Join Date
    Jul 2012
    Posts
    14

    Strange Run-time Error

    Hi guys, I'm writing a program but I ran into a run-time error. I know it sounds ambiguous but the issue only just came up when I wrote a few lines of code. The function is suppose to deal with cases where the first letters are upper case, but I get a run-time error before I even hit the first if statement where variable a is being tested. I tried outputting before the if statement and it shows on the console but output in the console doesnt occur. Why am I getting this run-time error? Thank you.
    Code:
    void piratify(string &s){
        //Changes specific words
        int caps=0;
        int a=(int)(s.at(0));
        if((a>=65)&&(a<=90)){
                  caps++;
          }
    
    
        if(s=="hello ")
            s="ahoy ";
        else if(s=="sir ")
            s="matey ";
        else if(s=="madam ")
            s="proud beauty ";
        else if(s=="officer ")
            s="foul blaggart ";
        else if(s=="stranger ")
            s="scurvy dog ";
        else if(s=="where ")
            s="whar ";
        else if(s=="is")
            s="be ";
        else if(s=="the ")
            s="th' ";
        else if(s=="my ")
            s="me ";
        else if(s=="your ")
            s="yer ";
        else if(s=="restaurant ")
            s="gallery ";
        else if(s=="hotel ")
            s="fleabag inn ";
        if(caps==1){
            s.at(0)-=32;
        }
    }
    Just in case anyone wants to see the whole code
    Code:
    #include<iostream>
    #include<string>
    #include<ctime>
    #include<cstdlib>
    using namespace std;
    void cleanup(string &s);
    void piratify(string &s);
    void ioncannon(string s, string &m,string p, char a);
    void pirate(string &s);
    void arr(string &s);
    void punctuation (string &s, char &a, string &p);
    void checker (string s, string b);
    int main()
    {
        string s;
        srand(time(0));
        cout<<"Enter string: ";
        getline(cin,s);
        cleanup(s);
        pirate(s);
        cout<<s;
        cin.get();
        cin.ignore();
    }
    void pirate(string &s){
        //Calls everything, with the substrings as variables
        int n=0,i=0,k=0;
        string c,m,p;
        char a;
        while(n!=-1){
            n=s.find(" ",i+1);
            c=s.substr(k,n+1-k);
            p=c;
            punctuation(c,a,p);
            piratify(c);
            ioncannon(c,m,p,a);
            k=n+1;
            i=n;
        }
        s=m;
    
    
    }
    void cleanup(string &s)
    {
        //Cleans string for easy reading
        string c,b;
        for(int i=0;i<s.length();i++){
            if(s.at(i)>=65&&s.at(i)<=90)
                s.at(i)+=32;
        }
        s.resize(s.length()+1,' ');
    }
    void piratify(string &s){
        //Changes specific words
        int caps=0;
        int a=(int)(s.at(0));
        if((a>=65)&&(a<=90)){
                  caps++;
          }
    
    
        if(s=="hello ")
            s="ahoy ";
        else if(s=="sir ")
            s="matey ";
        else if(s=="madam ")
            s="proud beauty ";
        else if(s=="officer ")
            s="foul blaggart ";
        else if(s=="stranger ")
            s="scurvy dog ";
        else if(s=="where ")
            s="whar ";
        else if(s=="is")
            s="be ";
        else if(s=="the ")
            s="th' ";
        else if(s=="my ")
            s="me ";
        else if(s=="your ")
            s="yer ";
        else if(s=="restaurant ")
            s="gallery ";
        else if(s=="hotel ")
            s="fleabag inn ";
        if(caps==1){
            s.at(0)-=32;
        }
    }
    void ioncannon(string s, string &m,string p, char a){
        //Adds everything back on
        int n=p.find_first_of(a);
        int k=s.length()-1;
        if(a!=' '&&n!=-1){
            s.at(k)=a;
            s+=' ';
        }
        m+=s;
        arr(m);
    }
    void punctuation (string &s, char &a, string &p){
        //Punctuation checker
        int find = s.find_first_of(",.?!");
        if(find!=-1){
            a = s.at(find);
            s.resize(find+1);
            p=s;
            s.at(find)=' ';
        }
    }
    void arr(string &s)
    {
        int n=0;
        n=rand()%2;
        if(n==1)
            s+="Arrr! ";
    
    
    }

  2. #2
    Registered User C_ntua's Avatar
    Join Date
    Jun 2008
    Posts
    1,853
    Can you elaborate what you mean by "run-time" error? Do you mean the program crashes?
    If that is the case a debugger is your friend (even your best buddy). If not for a debugger you can put some "count << "I am here!" << endl" statements to see what is the last line executed before it crashes. This will help generally for you to find the error or even if you just post the line it fails it will save the time for someone that tries to find the error for you here

  3. #3
    Registered User
    Join Date
    Jul 2012
    Posts
    14
    Yeah run-time error meaning it crashes. I actually tried outputting before and inbetween like I said before, it outputs a line of code BEFORE the if statement, but not one IN the if statement, even if I force a variable to fit my boundaries

  4. #4
    Registered User
    Join Date
    May 2010
    Posts
    4,633
    In a couple of places you are possibly invoking undefined behavior. For example the following snippet:
    Code:
    void punctuation (string &s, char &a, string &p){
        //Punctuation checker
        int find = s.find_first_of(",.?!");
    If find_first_of() fails to find one of your characters it will return std::string::npos which could overflow your int type since npos it the largest possible value that size_type can hold, which is usually much larger than what an int can hold. Overflowing a signed int causes undefined behavior. You should always use a size_type to hold the return value from the std::string::find() series of functions and then compare that return value to std::string::npos.

    Your problem is being caused by trying to access one of your strings past the size of the string. Check the values of the variables you are using in your std::string.at() calls to insure that they are within the bounds of the string.

    Jim

  5. #5
    Registered User
    Join Date
    Jul 2012
    Posts
    14
    And after much testing, you were right! Thank you so much jimblumberg and you too C_ntua. I just have a querie regarding your advice, what do you mean by "You should always use a size_type to hold the return value"? What is a size_type?

  6. #6
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by napalmgrenade View Post
    And after much testing, you were right! Thank you so much jimblumberg and you too C_ntua. I just have a querie regarding your advice, what do you mean by "You should always use a size_type to hold the return value"? What is a size_type?
    It's a typedef within the string class, ie:std::string::size_type. It typically maps to std::size_t which in turn is usually just a typedef for an unsigned int...
    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;
    }

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Sebastiani View Post
    ...It typically maps to std::size_t which in turn is usually just a typedef for an unsigned int...
    Or not, since Visual C++ maps it to a 64-bit type, because that's essentially that maximum numbers of elements specific containers (such as vector) can hold.
    Be careful with assumptions.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    Guest Sebastiani's Avatar
    Join Date
    Aug 2001
    Location
    Waterloo, Texas
    Posts
    5,708
    Quote Originally Posted by Elysia View Post
    Or not, since Visual C++ maps it to a 64-bit type, because that's essentially that maximum numbers of elements specific containers (such as vector) can hold.Be careful with assumptions.
    Wasn't assuming anything, actually; if I had I would have just told the OP to use an unigned int rather than the typedef, right?
    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;
    }

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strange ERROR
    By leo2008 in forum C Programming
    Replies: 6
    Last Post: 04-18-2012, 02:41 PM
  2. strange error... someone help please///
    By peter_hii in forum C++ Programming
    Replies: 28
    Last Post: 10-02-2006, 09:49 AM
  3. C++ VC6 to VC.NET - strange error
    By torbjorn in forum C++ Programming
    Replies: 9
    Last Post: 06-02-2004, 04:18 AM
  4. Strange Error
    By tyler4588 in forum C++ Programming
    Replies: 2
    Last Post: 07-23-2003, 07:02 PM
  5. Strange Error!
    By davidvoyage200 in forum C++ Programming
    Replies: 3
    Last Post: 02-22-2003, 07:58 PM