Thread: C to C++

  1. #1
    Registered User
    Join Date
    Oct 2008
    Posts
    115

    C to C++

    I have created a function in C that validates the user input for string. I'm trying to figure out how to convert it in C++. I don't know if some of the functions that I've used right here is allowed to be used in C++.

    Code:
    char *getString( int strSize )
    {
        char value;//, arrValue[ strSize ];
        char *str;
        char *rcvValue;
        int ctr = 0;
     
        //rcvValue = arrValue;
        rcvValue = malloc( 5 * sizeof( strSize ) );
        while( 1 )
        {
           value = getch();
           if( value == '\b' && ctr > 0 )
           {
              putch( value );
              putch( ' ' );
              putch( value );
              ctr--;
           }
           else if( value != '\b' && value != '\r' && ctr != 30 )
           {
              
              if( isspace( value ) || isalpha( value ) )
              {
                 //arrValue[ ctr ] = value;
                 rcvValue[ ctr ] = value;
                 putch( value );
                 ctr++;
              }
           }
                
           if( value == '\r' )
           {
              if(  ctr > 0 )
                 break;
           }
        }
        
        rcvValue[ ctr ] = '\0';
        //arrValue[ ctr ] = '\0';
        //rcvValue = malloc( strlen( arrValue ) + 1 );
        return rcvValue;
    }

  2. #2
    Registered User
    Join Date
    Dec 2006
    Location
    Canada
    Posts
    3,229
    First of all,
    Code:
    rcvValue = malloc( 5 * sizeof( strSize ) );
    doesn't make sense.

    sizeof(strSize) is the same as sizeof(int). Probably not what you want.

    Syntactically, adding a cast for the return value of malloc and it will probably work. Why convert to C++ if you are only going to use C functions, though?

  3. #3
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    All C functions and almost all other C syntax can be used in C++.
    Why not just change your file from foo.c to foo.cpp and try compiling it and see if you get any errors?
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  4. #4
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    There are two options when "converting C to C++":
    1. Do the minimal necessary to make it compile. For example putting casts where malloc's return value is given to the pointer.
    2. Make it "proper" C++ code - in this case, replacing malloc with new, for example.


    --
    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
    Jun 2005
    Posts
    6,815
    I assume in the following the real objective of the original question is getting some old C code to compile with a C++ compiler. Strictly speaking, that is not "conversion" of C to C++.

    Given that the code uses getch() and putch(), the original code is not, strictly speaking, valid C either. Those functions are non-standard extensions that read characters without echoing, and no equivalent functions exist in standard C or C++. Given that your code is using those functions, any translation you do to C++ will also rely on non-standard extensions.

    You will need to #include headers that declare the functions you use. C (at least before the 1999 standard) functions are assumed to return int if they are called without being previously declared. Code that relies on that behaviour will generate a compilation error in C++ - and casting the return from malloc() will not fix that. Within the C standard, malloc() is declared in <stdlib.h>, isspace() and isalpha() are in <ctype.h>, and strlen() is in <string.h> - although deprecated, those headers are currently supported in C++.

    Assuming your code is targeting windows, getch() and putch() are declared in the non-standard header <conio.h>.

    There are other things that can be done to make the code more idiomatic C++, but if your objective is to get your code to compile with a C++ compiler the above is enough.

  6. #6
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    On a completely differnet note:
    Code:
              putch( value );
              putch( ' ' );
              putch( value );
    is bad in my mind. It would be better to do:
    Code:
        puts("\b \b");
    This also allows you to change what the back-space key actually is, without having to change anything else.

    Code:
           if( value == '\r' )
           {
              if(  ctr > 0 )
                 break;
           }
        }
    Why is this written with two if-statements, and all the other cases written with a combined condition?

    Code:
           else if( value != '\b' && value != '\r' && ctr != 30 )
    Should 30 not be strsize?

    Code:
        char *str;
    Unused, as far as I can see.

    I know, you didn't ask for a code-review, but I can't help myself sometimes.

    --
    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.

  7. #7
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    Given that the code uses getch() and putch(), the original code is not, strictly speaking, valid C either.
    O_o

    No. That's interpretive; strictly speaking, the code is perfectly valid C(89). You are assuming a particular meaning for 'getch' and 'putch'; a compiler will only assume a particular signature.

    This also allows you to change what the back-space key actually is, without having to change anything else.
    You've only made the source more brittle; that code only executes when 'value' is '\b'. Your change would mean requiring an update in at least three places instead of just one if the actual representation for '\b' changed.

    Soma

  8. #8
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by phantomotap View Post
    You've only made the source more brittle; that code only executes when 'value' is '\b'. Your change would mean requiring an update in at least three places instead of just one if the actual representation for '\b' changed.

    Soma
    What I meant is that if you ever have a "backspace" key on the keyboard that returns (for example) "delete" [but you still want it to behave as backspace, not delete], then the code posted would be broken, since [I'm assuming] getch() is a function that returns exactly the key that was processed.

    If the if-statement is changed so that '\b' is not '\b' but '\x07f', the code would break. The definition in the standard is that '\b' is backspace, so that is correct. However, the definition from the standard says NOTHING about which key on the keyboard returns that value, nor what the application/user may see fit as using for the operation of "delete previous character" - I hate when I have to press CTRL-H because the application doesn't recognize my backspace key as a backspace, but sends some other contol-code.

    Note that printing 0x7f will NOT have the effect of printing '\b'.

    --
    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.

  9. #9
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by phantomotap View Post
    No. That's interpretive; strictly speaking, the code is perfectly valid C(89).
    Well, yeah, I suppose. But note my assumption at the start of my post. Even without that assumption, the code is only "valid C" if your definition includes code that might compile but will never link or run on some platforms. And the intent of the C standard is to specify characteristics of code that can be compiled and executed consistently (or not, in specified manners) between platforms.
    Quote Originally Posted by phantomotap View Post
    You are assuming a particular meaning for 'getch' and 'putch'; a compiler will only assume a particular signature.
    The code provided neither declares nor defines them in any way way (not as a macro, not a function prototype, etc). That means the code is relying (implicitly) on getch() and putch() being defined in some manner.

    And note that a C99 compiler will not assume a particular signature unless told to (i.e. it sees a macro or a function declaration).

    The usage pattern of getch() and putch() is also completely consistent with the particular windows <conio.h> functions.

    I suppose the middle ground between your pickiness and mine is that those functions are problematic in the code, unless we assume some things that the original poster left out.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  10. #10
    Registered User
    Join Date
    Oct 2008
    Posts
    115
    Quote Originally Posted by cyberfish View Post
    First of all,

    doesn't make sense.

    sizeof(strSize) is the same as sizeof(int). Probably not what you want.

    Syntactically, adding a cast for the return value of malloc and it will probably work. Why convert to C++ if you are only going to use C functions, though?
    I'm only running the program in console in C++. Since I truly like the validation I created in C, I wanted to apply it in C++ to provide a strong validation as well for user input. I know that all of you already know what the program can do. The idea of converting this to C++ is not bad right, because most of the functions right there came from C? The blue colored code is changed.

    Code:
    char *getString( int strSize )
    {
        char value;//, arrValue[ strSize ];
        //char *str; I forgot to comment this out
        char *rcvValue;
        int ctr = 0;
     
        //rcvValue = arrValue;
        //rcvValue = malloc( 5 * sizeof( int ) );
        rcvValue = new char[ strSize + 1 ];
        while( 1 )
        {
           value = getch();
           if( value == '\b' && ctr > 0 )
           {
              /*putch( value );
              putch( ' ' );
              putch( value );*/
              puts( "\b \b" );
              ctr--;
           }
           else if( /*value != '\b' && value != '\r' &&*/ ctr != 30 )
           {
              
              if( isspace( value ) || isalpha( value ) )
              {
                 rcvValue[ ctr ] = value;
                 putch( value );
                 ctr++;
              }
           }
           else  if( value == '\r' )
           {
              if(  ctr > 0 )
                 break;
           }
        }
        
        rcvValue[ ctr ] = '\0';
     
        return rcvValue;
    }
    Last edited by $l4xklynx; 03-06-2009 at 05:57 AM.

  11. #11
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Code:
           else if( /*value != '\b' && value != '\r' &&*/ ctr != 30 )
    Do you really NOT want the '\r' in there? - you could of course move the check for return up BEFORE this line (or use a switch, which I would probably have done - but when have written functions like this, I tend to implement more editing functions).

    And I still think 30 is an incorrect hard-coded constant here!

    And of course, if you where to use std::string, it would make it a lot more C++.

    --
    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.

  12. #12
    Registered User
    Join Date
    Oct 2008
    Posts
    115
    Quote Originally Posted by matsp View Post
    Code:
           else if( /*value != '\b' && value != '\r' &&*/ ctr != 30 )
    Do you really NOT want the '\r' in there? - you could of course move the check for return up BEFORE this line (or use a switch, which I would probably have done - but when have written functions like this, I tend to implement more editing functions).

    And I still think 30 is an incorrect hard-coded constant here!

    And of course, if you where to use std::string, it would make it a lot more C++.

    --
    Mats
    Code:
           else if( /*value != '\b' && */ value != '\r' &&  ctr != strSize )
           {
              
              if( isspace( value ) || isalpha( value ) )
              {
                 rcvValue[ ctr ] = value;
                 putch( value );
                 ctr++;
              }
           }
    If i'm going to use string in C++ I can actually apply the function I created? Because my objective to my function right there is to stop the cursor to the 30th or to whatever size was passed to the parameter to avoid the user to enter more than the size specified and also to avoid buffer overflow.

    Quote Originally Posted by grumpy
    There are other things that can be done to make the code more idiomatic C++, but if your objective is to get your code to compile with a C++ compiler the above is enough.
    Any example of things that can be done to make it more idiomatic C++?

    Quote Originally Posted by cpjust
    All C functions and almost all other C syntax can be used in C++.
    Why not just change your file from foo.c to foo.cpp and try compiling it and see if you get any errors?
    I'm in the office right now, I'll try at home and reply asap with the updated code.

  13. #13
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    To use this function with std::string would require a bit of working around the function, but it wouldn't require a LOT of workaround, in my mind.

    --
    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.

  14. #14
    Master Apprentice phantomotap's Avatar
    Join Date
    Jan 2008
    Posts
    5,108
    If the if-statement is [...] some other contol-code.
    I see. You were talking about handling a change in how the particular user event of "hitting the backspace key" is presented to the software by the keyboard layout/driver and interpreted by the implementation. I did misunderstand. As far as that goes, nothing so simple is going to work; the wireless keyboard and drivers I use send a control key, an interpreted key ('\b'), and another control key which the implementation of 'CONIO' I have on hand prints, using the posted source, as "^^".

    Well, yeah, I suppose. But note [...] between platforms.
    You've excluded all source. No code, no matter how conforming, will run exactly as the standard specifies on every platform. I can, at my leisure, write fully conforming C++ that will not compile and run on any platform I have at my disposal. That definition of valid is meaningless. Invalid code would be something that the standard strictly forbids.

    The code provided [...]defined in some manner.
    I suppose the middle [...] original poster left out.
    I suppose the middle [...] the original poster left out.
    The code provided doesn't have a 'main' either. That doesn't change the validity of the sample.

    The blue colored code is changed.
    Wonderful.

    Now move the terminating condition, the 'if' statements around the 'break', directly to the condition of the 'while' statement.

    Don't pointlessly over-allocate, if you are going to stick with the constant (30); allocate the smaller of 31 or 'strSize + 1'.

    To use this function [...] require a LOT of workaround, in my mind.
    If he uses the right construct he only needs to change three lines four lines or abut 60 70 characters.

    Soma
    Last edited by phantomotap; 03-06-2009 at 06:25 AM.

  15. #15
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Phantomotap
    Quote Originally Posted by matsp
    To use this function [...] require a LOT of workaround, in my mind.
    If he uses the right construct he only needs to change three lines four lines or abut 60 70 characters.
    The bit quoted is this:
    To use this function with std::string would require a bit of working around the function, but it wouldn't require a LOT of workaround, in my mind.
    Now, your ... covers some important information, including the "would NOT" that I've made bold in the quote above. So, four lines is not a lot. I did not really try to figure out how many lines there are that require changing, but four lines sounds about right.

    --
    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.

Popular pages Recent additions subscribe to a feed