#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0

    Int to String Fail


    I thought this would be pretty straightforward. I am trying to convert an integer to a string. It seems most posts on stack overflow suggest something like this:

    Code:
    	stringstream ss;
    	ss << number;
    	return ss.str(); // function is to return a string
    However, the error I get is this:
    error: invalid conversion from ‘int’ to ‘const char*’ [-fpermissive]

    What could be wrong?
  2. #2
  3. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    What datatype are you trying to return? That the error message makes reference to char* makes me wonder.

    stringstream works with the basic string class. If you RTFM! ("Read The Manual!") on stringstream and then on its str() method, you will see that str() returns string. If the function is supposed to return a C-style string (as indicated by the char*) instead of a basic string object, then what you have would not work.

    Back in the day (ie, pre-1998 which introduced stringstream) when C++ still used C-style strings, we had strstream which worked with C-style strings. cplusplus.com reference doesn't seem to carry it anymore (some nonsense about it being deprecated), but I'd be willing to bet that its str() method returned a C-style string.

    So if you don't feel like using strstream, then at least convert that string output to a C-style string; eg:
    return ss.str().c_str();

    And if that wasn't the problem, then why didn't you give us enough information to work with? No function header, so I had to guess. No indication of which line of code actually threw that error message, so again I had to guess.

    Actually, a short program that illustrated the problem and that we could compile and examine ourselves would have really helped out.

    So long as you withhold information, keep us in the dark, and force us to guess, then the quality of our responses must naturally suffer for it.
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Sorry.

    Code:
    string Randomizer::getRandomIntAsString() {
    	srand(static_cast<unsigned int>(time(NULL)));
    	int number = (rand() % getRange()) + low; // getRange() and low are both ints
    	stringstream ss;
    	ss << number;
    	return ss.str(); // error points to this line
    }
    Also I am using Eclipse if that is relevant.
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    For something small and compilable:

    Code:
    string getRandomIntAsString() {
    	srand(static_cast<unsigned int>(time(NULL)));
    	int number = (rand() % 100) + 1;
    	stringstream ss;
    	ss << number;
    	return ss.str(); // error points to this line
    }
    
    int main() {
           string test = getRandomIntAsString();
           cout << test;
           return 0;
    }
  8. #5
  9. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    No #include statements? No namespace being used? Is that what your complete program is like?

    Considering all the error messages you would be getting, you should correct those before worrying about this one. Often, one error will cause several other errors to appear after it, so clearing up the initial error will also clear up those others.
  10. #6
  11. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Correcting for those failings, I came up with this:
    Code:
    #include <sstream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    string getRandomIntAsString() 
    {
    	srand(static_cast<unsigned int>(time(NULL)));
    	int number = (rand() % 100) + 1;
    	stringstream ss;
    	ss << number;
    	return ss.str(); // error points to this line
    }
    
    int main() 
    {
           string test = getRandomIntAsString();
           cout << test;
           return 0;
    }
    All I did was add the #include and the using statements, plus move those hidden open braces out to their proper level of indentation.

    Here is what I get when I compile that:
    C:TEST>g++ -Wall adampjr1.cpp

    C:TEST>
    No errors. No warnings.

    I cannot duplicate your problem.

    Please ensure that your short complete program still displays the problem that you reported. Also copy and paste all the warnings and errors that you get. As well as to inform us of what compiler you used; I used MinGW gcc on WinXP.

    PS

    Sample runs:
    C:TEST>a
    76
    C:TEST>a
    80
    C:TEST>a
    86
    C:TEST>a
    90
    C:TEST>a
    93
    C:TEST>a
    93
    C:TEST>
    Last edited by dwise1_aol; December 19th, 2013 at 11:21 AM.
  12. #7
  13. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Ok thanks. That works for me too. I am trying to narrow down the issue to a simple code that still has the problem, obviously it's not what I thought it was.

    I'll post that here if I can get it narrowed down to what the actual issue.
  14. #8
  15. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Something just occurred to me. I changed that working program ever so slightly by placing the function after the function that calls it:
    Code:
    #include <sstream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    int main() 
    {
        string test = getRandomIntAsString();
        cout << test;
        return 0;
    }
    
    string getRandomIntAsString() 
    {
        srand(static_cast<unsigned int>(time(NULL)));
        int number = (rand() % 100) + 1;
        stringstream ss;
        ss << number;
        return ss.str(); // error points to this line
    }
    Please note that main tries to call getRandomIntAsString() before that function has been declared. Also, I did not provide any prototype for getRandomIntAsString().

    Here is what my compiler tells me:
    C:TEST>g++ -Wall adampjr1.cpp
    adampjr1.cpp: In function `int main()':
    adampjr1.cpp:9: implicit declaration of function `int getRandomIntAsString(...)'

    adampjr1.cpp:9: conversion from `int' to non-scalar type `basic_string<char,string_char_traits<char>,__default_alloc_template<false,0> >' requested

    C:TEST>
    Did you try something similar? Did you get any warnings or error messages complaining about getRandomIntAsString being implicitly declared?

    In your original program, place a prototype for getRandomIntAsString() at the top of the file, below the #include and using statements. Eg:
    Code:
    #include <sstream>
    #include <cstdlib>
    #include <ctime>
    
    using namespace std;
    
    // prototype for getRandomIntAsString, so that the 
    //     call in main will know about the function.
    string getRandomIntAsString(); 
    
    int main() 
    {
        string test = getRandomIntAsString();
        cout << test;
        return 0;
    }
    
    string getRandomIntAsString() 
    {
        srand(static_cast<unsigned int>(time(NULL)));
        int number = (rand() % 100) + 1;
        stringstream ss;
        ss << number;
        return ss.str(); // error points to this line
    }
    See if that clears it up.
    Last edited by dwise1_aol; December 19th, 2013 at 12:13 PM.
  16. #9
  17. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Originally Posted by dwise1_aol
    Often, one error will cause several other errors to appear after it, so clearing up the initial error will also clear up those others.
    I had all my includes but this was the solution here.

    I also had an error in a hardly related header file about something else. The header file was doubly included. I realized I didn't even need it, so I just deleted it.

    getRandomIntAsString is in a class Randomizer (otherwise the code was the same as I posted except that main created a Randomizer() and then sent its function to cout). And now that I deleted the messed up header file it works just like the simple program that worked for you. I'm confused as to why it would throw that error when the only thing I had to fix to get it to work was the header file error, but I'm back in business.

    Thanks.
  18. #10
  19. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    I don't know what your practices are.

    The effects of doubly included headers can be prevented with guard defines (which also have other names which I cannot recall). From the very beginning in C, this is what I was taught to do with every header file:
    Code:
    // _THISHEADER_H_ is a macro based on the name of the header file 
    //     eg, for defines.h it would be _DEFINES_H_
    // That's just my convention for making the macro unique.  Feel free to come up with your own.
    
    #ifndef _THISHEADER_H_
    #define _THISHEADER_H_
    
    // here is where you place the body of the header
    
    #endif  // _THISHEADER_H_
    // end of file
    The first time the header is included in the source file, _THISHEADER_H_ is not defined. Therefore, #ifndef (if not defined) is true and the body of the header file is parsed. The very first thing that is done is to define _THISHEADER_H_. If the header file is included again, then _THISHEADER_H_ will be defined and the body of the header file will not be parsed -- it will be excluded from the program. This way, no matter how many times the same header file gets included into a source file, it will only be used once.

    The principle that is used is called "conditional compilation" and is widely used.

    Also bear in mind that in C and C++, every source file is compiled separately and independently, so when you have compiled one source file that includes thisheader.h and then you compile a second source that includes thisheader.h, the macro _THISHEADER_H_ will again not be defined at the start of that second compilation. To add a little more detail, compiling does not generate an executable, but rather an object file. It is the linker that then links together all the object and library files to create an executable file. Therefore, the compiler generates each individual object file separately and independently of each other. Your "compiler" (actually a development environment) performs all those steps automatically such that it only looks to you that one program, the compiler, is doing all of it.

    And as I had mentioned before, a great many of the more baffling errors are actually caused by something else farther up the source code that went wrong. A common example is forgetting a semicolon in a long list of declarations, which causes one identifer to fail to be declared. Then everywhere else in the program that that identifier is used will also fail; this becomes especially bad if it's a datatype definition that failed. That is why it's always best to start with the first errors and warnings.
  20. #11
  21. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2013
    Posts
    13
    Rep Power
    0
    Originally Posted by dwise1_aol
    I don't know what your practices are.

    The effects of doubly included headers can be prevented with guard defines (which also have other names which I cannot recall). From the very beginning in C, this is what I was taught to do with every header file:
    Code:
    // _THISHEADER_H_ is a macro based on the name of the header file 
    //     eg, for defines.h it would be _DEFINES_H_
    // That's just my convention for making the macro unique.  Feel free to come up with your own.
    
    #ifndef _THISHEADER_H_
    #define _THISHEADER_H_
    
    // here is where you place the body of the header
    
    #endif  // _THISHEADER_H_
    // end of file
    The first time the header is included in the source file, _THISHEADER_H_ is not defined. Therefore, #ifndef (if not defined) is true and the body of the header file is parsed. The very first thing that is done is to define _THISHEADER_H_. If the header file is included again, then _THISHEADER_H_ will be defined and the body of the header file will not be parsed -- it will be excluded from the program. This way, no matter how many times the same header file gets included into a source file, it will only be used once.

    The principle that is used is called "conditional compilation" and is widely used.

    Also bear in mind that in C and C++, every source file is compiled separately and independently, so when you have compiled one source file that includes thisheader.h and then you compile a second source that includes thisheader.h, the macro _THISHEADER_H_ will again not be defined at the start of that second compilation. To add a little more detail, compiling does not generate an executable, but rather an object file. It is the linker that then links together all the object and library files to create an executable file. Therefore, the compiler generates each individual object file separately and independently of each other. Your "compiler" (actually a development environment) performs all those steps automatically such that it only looks to you that one program, the compiler, is doing all of it.

    And as I had mentioned before, a great many of the more baffling errors are actually caused by something else farther up the source code that went wrong. A common example is forgetting a semicolon in a long list of declarations, which causes one identifer to fail to be declared. Then everywhere else in the program that that identifier is used will also fail; this becomes especially bad if it's a datatype definition that failed. That is why it's always best to start with the first errors and warnings.
    Thanks for all this. I didn't have all that in my header file.

    Off my original topic, how useful are header files (aside from the ones for class definitions)?

    I obviously don't know what I'm doing in C++, I'm more used to Java where things are a bit different. I'm used to thinking of everything as being part of a class - and if I wanted a global I would just make it a static member of a class everything had access to. Is the the header approach more practical?
  22. #12
  23. Contributing User
    Devshed Supreme Being (6500+ posts)

    Join Date
    Jan 2003
    Location
    USA
    Posts
    7,145
    Rep Power
    2222
    Header files are absolutely essential in C and C++ programming. The reason is because of what I already told you: "... bear in mind that in C and C++, every source file is compiled separately and independently ...".

    In any non-trivial project, there are multiple source files. This is true both of Java and of C++. Many of those source files will reference something that is defined in another source file, which means that the compiler needs to know about those somethings in the other source files. As I understand it in Java (it's been about a decade), the compiler will look at the other .java source files , meaning that the compiler will make itself aware of the other source files. In C++, as it inherited from C (or I'll refer to the two as "C/C++"), the compiler knows nothing about what's in the other source files nor is it at all curious so it doesn't go looking. In C/C++ we have to provide that information to the compiler and we do that through header files.

    So to put it succinctly, we place into header files all the information that source files will need to know about other source files. Header files are how source files communicate with all the other source files.

    Every C/C++ programmer learns the build process -- sorry, but I learned it in the very beginning back circa 1990. From memory, I will try to describe it briefly:

    1. Compilation. One by one, each source file is compiled to generate an object file. The object file contains the source file's code translated to object code, which is close to the machine code that the computer actually executes. What's missing are the addresses of variables and functions that the file references but which are in other object files; that will be resolved by the linker. The object file also contains tables of the objects, variables, and functions that it provides to the rest of the project and of the ones that it needs to have resolved.

    The first step of the compilation step is pre-processing, in which the source file is prepared for parsing and translation, creating an temporary modified version of the source file which is what the compiler actually processes. The pre-processor scans the source file for pre-processor directives, which are identified by starting with hash marks (#). Macros are defined (#define) or undefined (#undef). Wherever macros are encountered in the code, those macro names are replaced by their defined values (this is called macro expansion and is not restricted to C/C++). Conditional compilation determines whether to include or exclude sections of code depending of whether a macro is defined or not (eg, #ifdef, #ifndef, #if, #else, #endif). And files marked for insertion into the source file (via #include statements) are inserted into the source file.

    That is how header files are actually used. Because of the #include statement, the entire header file is inserted into the source file at that point and its code becomes part of the source file.

    The next steps of the compilation phase involve the scanning and parsing of the modified source code, the building of tables of references, the translation of source code into object code, and the creation of the object file.

    I will repeat here that every single source file is compiled separately and independently of all the other source files. That is why each source file that references something in another source file or needs data definitions must #include the header files that contain that information.

    Step 2. Linking. After all the source files have been compiled and their object files have been generated, the linker uses those object files to generate an executable file.

    Comments on this post

    • adampjr agrees : Very helpful

IMN logo majestic logo threadwatch logo seochat tools logo