Invalid conversion from 'char' tp 'char*'

Discussion in 'C++' started by Tim Johansson, Apr 7, 2004.

  1. I'm new to C++, and tried to start making a script that will shuffle an
    array. Can someone please tell me what's wrong?

    #include <iostream.h>
    #include <string.h>

    int main () {
    srand(time(0));
    int array_length;
    int count;
    int randm;
    char temp[30];
    cout << "How many items in array? ";
    cin >> array_length;
    char items [30][array_length + 1];
    for (count = 0; count <= array_length; count++) {
    if (count != 0) {
    cout << "\nWhat shall item " << count << " be?\n\t";
    }
    cin.getline (items[count], 30);
    }
    for (count = 0; count < array_length; count++) {
    randm = rand() % array_length;
    strcpy (temp[30], items[30][count]);
    //ERROR
    strcpy (items[30][count], items[30][randm]); //ERROR
    strcpy (items[30][randm], temp[30]); //ERROR
    }
    return 0;
    }


    Can someone please tell me what is wrong? The errors I get are:
    21: error: invalid conversion from 'char' to 'char*'
    21: error: invalid conversion from 'char' to 'const char*'
    22: error: invalid conversion from 'char' to 'char*'
    22: error: invalid conversion from 'char' to 'const char*'
    23: error: invalid conversion from 'char' to 'char*'
    23: error: invalid conversion from 'char' to 'const char*'
     
    Tim Johansson, Apr 7, 2004
    #1
    1. Advertising

  2. Tim Johansson

    Petec Guest

    Tim Johansson wrote:
    > I'm new to C++, and tried to start making a script

    ^^^^^^
    FYI, C++ programs are not "scripts", they're programs.

    > that will shuffle
    > an array. Can someone please tell me what's wrong?
    >

    <snip>

    I'm not sure what was wrong (I couldn't understand it) but here's a little
    shuffle program:

    int main()
    {
    // a vector of strings to hold the items
    std::vector<std::string> items;

    // get items
    std::cout << "Enter items, or blank to finish:" << std::endl;
    for(;;)
    {
    std::string item;
    std::getline(std::cin, item);
    if(item == "")
    break;
    items.push_back(item);
    }


    std::cout << std::endl << "Shuffled items:" << std::endl;

    // use the random_shuffle algorith in <algorithm> to shuffe the sequence
    std::random_shuffle(items.begin(), items.end());

    // copy the shuffled vector to std::cout
    std::copy(items.begin(), items.end(),
    std::eek:stream_iterator<std::string>(std::cout, "\n"));
    }

    Also, I suggest you read the free & legal "Thinking in C++" book by Bruce
    Eckel, availible at the author's website, www.mindview.net.

    - Pete
     
    Petec, Apr 7, 2004
    #2
    1. Advertising

  3. Tim Johansson

    Ragemare Guest

    "Tim Johansson" <> wrote in message
    news:c51l09$2nosfd$-berlin.de...
    > I'm new to C++, and tried to start making a script that will shuffle an
    > array. Can someone please tell me what's wrong?
    >
    > #include <iostream.h>
    > #include <string.h>
    >
    > int main () {
    > srand(time(0));
    > int array_length;
    > int count;
    > int randm;
    > char temp[30];
    > cout << "How many items in array? ";
    > cin >> array_length;
    > char items [30][array_length + 1];
    > for (count = 0; count <= array_length; count++) {
    > if (count != 0) {
    > cout << "\nWhat shall item " << count << " be?\n\t";
    > }
    > cin.getline (items[count], 30);
    > }
    > for (count = 0; count < array_length; count++) {
    > randm = rand() % array_length;
    > strcpy (temp[30], items[30][count]);
    > //ERROR
    > strcpy (items[30][count], items[30][randm]); //ERROR
    > strcpy (items[30][randm], temp[30]);

    //ERROR
    > }
    > return 0;
    > }
    >
    >
    > Can someone please tell me what is wrong? The errors I get are:
    > 21: error: invalid conversion from 'char' to 'char*'
    > 21: error: invalid conversion from 'char' to 'const char*'
    > 22: error: invalid conversion from 'char' to 'char*'
    > 22: error: invalid conversion from 'char' to 'const char*'
    > 23: error: invalid conversion from 'char' to 'char*'
    > 23: error: invalid conversion from 'char' to 'const char*'
    >
    >


    Not that I'm a expert but you appear to be trying to pass a single segment
    of the array instead of all of the array, get rid of the '[30]'. Also I
    don't think you can pass a two dimentional array to strcpy.
     
    Ragemare, Apr 7, 2004
    #3
  4. Tim Johansson wrote:

    > I'm new to C++, and tried to start making a script that will shuffle an
    > array. Can someone please tell me what's wrong?
    >
    > #include <iostream.h>


    This is not a standard header. Standard C++ uses <iostream>. This
    suggests that you are learning from a source that is either very
    outdated, inaccurate, or (most likely) both.

    > #include <string.h>


    This is standard, but deprecated. <cstring> is the replacement.

    >
    > int main () {
    > srand(time(0));


    Where did srand() and time() come from? You haven't #included the
    appropriate headers for these. Those headers are <cstdlib> and <ctime>,
    respectively. Alternatively, the old deprecated versions are <stdlib.h>
    and <time.h>.

    If you use the first, non-deprecated versions, the functions will be in
    namespace std::, and you need to account for that. So, for example, you
    could do this:

    std::srand(std::time(0));

    Note also, that seeding the random number generator isn't always a good
    idea. You are debugging your program -- consistency is good during this
    phase. If you don't seed the random number generator (or seed it with
    some constant value, like 7), then you'll get the same sequence of
    numbers on each run, which makes debugging much easier.

    > int array_length;
    > int count;
    > int randm;
    > char temp[30];


    Consider using std::strings instead of char arrays. They are safer, more
    flexible, easier, and less error-prone.

    Don't declare everything up front. Declare things where you use them. It
    makes the code more clear, and someone reading the code does not need to
    search as much for the declaration of an object.

    > cout << "How many items in array? ";


    cout, cin, etc. are all in namespace std::, and you need to account for
    this somehow. So, for example, you could use this:

    std::cout << "some output" << std::endl;
    std::cin >> some_var;

    > cin >> array_length;


    What if this input operation fails? You should check for success. If it
    fails, array_length will have an undefined value. Using it for anything
    other than giving it a defined value would be bad.

    > char items [30][array_length + 1];


    This is illegal. Your compiler should reject it. If it doesn't, check
    the documentation about how to invoke it in standards-compliant mode.

    The problem is that array sizes must be compile-time constants.
    array_length + 1 is not known at compile-time.

    You should also prefer standard containers to arrays. std::vector is
    almost a drop-in replacement for arrays, and is more flexible and
    potentially safer.

    It appears that a good replacement for this would be

    std::vector<std::string> items(array_length + 1);

    > for (count = 0; count <= array_length; count++) {


    Not a major issue, but prefer pre-increment to post-increment when the
    end result is the same. pre-inc may be faster, and is almost certainly
    not slower, than post-inc. This probably makes no difference with
    built-in types, but it's a good habit nonetheless.

    > if (count != 0) {
    > cout << "\nWhat shall item " << count << " be?\n\t";
    > }
    > cin.getline (items[count], 30);


    This is wrong. What happens when 'count' is 500? The first index of
    'items' only goes to 29, so you are potentially overflowing your array
    bounds and invoking undefined behavior. Also, 30 may be more characters
    than can fit in 'items[count]'. Basically, you reversed your indices in
    the declaration (which, as I mentioned, was illegal anyway because one
    of the sizes was not a compile-time constant).

    After fixing all this, you still need special handling for when the line
    is longer than your maximum string size.

    If you used std::strings instead of char arrays, you could do this:

    std::getline(items[count]);

    Easier, safer, almost impossible to get wrong, not limited to some
    arbitrary length.

    > }
    > for (count = 0; count < array_length; count++) {
    > randm = rand() % array_length;


    For various reasons, this is a poor way to limit rand()'s range. The
    comp.lang.c FAQ has information on this. But for simple cases, it rarely
    matters much.

    > strcpy (temp[30], items[30][count]);


    This is wrong. temp[30] doesn't exist, nor does
    items[30][any_value_here]; Array bounds in C++ go from 0 to array_size-1.

    Besides that, there is a type mismatch. strcpy() expects arguments of
    type char* (const char* in the case of the source string), and you are
    passing char. This is precisely what your error message says. You
    probably wanted something like:

    std::strcpy(temp, items[count]);

    This assumes a few other changes in the code:

    1) The std:: qualification assumes #include <cstring> instead of
    #include <string.h>.

    2) items[count] is only valid if you reverse the indices in the
    declaration of items.

    Better still, get rid of the arrays and use vectors and strings like
    I've mentioned a few times:

    std::string temp;
    std::vector<std::string> items;

    //...

    // No need for special functions when dealing with
    // std::string -- the normal operators work fine:
    temp = vector[count];

    > //ERROR
    > strcpy (items[30][count], items[30][randm]); //ERROR
    > strcpy (items[30][randm], temp[30]); //ERROR


    Same basic problems here.

    > }
    > return 0;
    > }
    >


    Finally, the standard library provide the function std::random_shuffle()
    that does what you want.

    >
    > Can someone please tell me what is wrong? The errors I get are:
    > 21: error: invalid conversion from 'char' to 'char*'
    > 21: error: invalid conversion from 'char' to 'const char*'


    The errors could hardly be more clear. The function you are calling
    expects char* and const char* arguments, you passed char arguments.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Apr 7, 2004
    #4
  5. Ragemare wrote:

    >
    > Not that I'm a expert but you appear to be trying to pass a single segment
    > of the array instead of all of the array, get rid of the '[30]'.


    "Single element", not "single segment", but basically that's correct
    (though there are several other problems).

    > Also I
    > don't think you can pass a two dimentional array to strcpy.
    >


    You can't pass any array (directly) to a function ever, regardless of
    dimensions. Arrays aren't "first-class citizens" in C++. Any function
    that appears to take (or return) an array actually takes (or returns) a
    pointer.

    A function may, however, take (or return) a class that contains an
    array, or a reference to an array.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Apr 7, 2004
    #5
  6. Tim Johansson <> spoke thus:

    > #include <iostream.h>


    It's called <iostream> - the .h headers are deprecated.

    > #include <string.h>


    > int main () {
    > srand(time(0));
    > int array_length;
    > int count;
    > int randm;
    > char temp[30];
    > cout << "How many items in array? ";
    > cin >> array_length;
    > char items [30][array_length + 1];

    ^^^^^^^^^^^^
    I assume this is legal in C++, but I'd love it if a real C++ person
    stated something authoratative. As an aside, if you're making the
    array array_length+1 items long, then array_length isn't really, is
    it?

    > for (count = 0; count <= array_length; count++) {
    > if (count != 0) {
    > cout << "\nWhat shall item " << count << " be?\n\t";
    > }
    > cin.getline (items[count], 30);

    ^^
    Why not lose the magic number? Your code looks like C, so why not
    keep the theme going and use

    cin.getline( items[count], sizeof(items)/sizeof(*items) );

    ? That way if you change the number of items, you don't have to
    remember to change the call to getline.

    > }
    > for (count = 0; count < array_length; count++) {
    > randm = rand() % array_length;
    > strcpy (temp[30], items[30][count]);


    Here's the problem (well, besides that you're using C-style strings at
    all): strcpy is prototyped as

    char *strcpy( char *s, const char *t );

    What is temp[30]? It's a char, of course. And what is
    items[30][count]? It's a char, too. No wonder it doesn't compile,
    eh?

    And any particular reason you're ignoring the last string in items? If you
    had made array_length the actual length of the array, you'd be fine (in this
    snippet, at least), but you didn't.

    > strcpy (items[30][count], items[30][randm]); //ERROR
    > strcpy (items[30][randm], temp[30]); //ERROR
    > }
    > return 0;
    > }


    Either read a C book or learn how to use std::strings and std::vectors
    - I recommend the latter.

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Apr 7, 2004
    #6
  7. Tim Johansson

    Petec Guest

    Christopher Benson-Manica wrote:
    > Tim Johansson <> spoke thus:
    >

    <snip>
    >
    >> cin >> array_length;
    >> char items [30][array_length + 1];

    > ^^^^^^^^^^^^
    > I assume this is legal in C++, but I'd love it if a real C++ person
    > stated something authoratative. <snip>


    Nope, it's not legal. You'd either have to use arrays dynamically allocced
    with new, or std::vectors or another appropriate standard container.

    - Pete
     
    Petec, Apr 7, 2004
    #7
  8. Petec <> spoke thus:

    > Nope, it's not legal. You'd either have to use arrays dynamically allocced
    > with new, or std::vectors or another appropriate standard container.


    Well, that's what *I* would have done, but I didn't want to say "NO!"
    and then have to wipe more egg off my face than usual :)

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Apr 7, 2004
    #8
  9. Christopher Benson-Manica wrote:

    > Tim Johansson <> spoke thus:
    >
    >
    >>#include <iostream.h>

    >
    >
    > It's called <iostream> - the .h headers are deprecated.
    >


    It's true that those headers which are part of the standard and which
    end in .h are deprecated, but <iostream.h> is not even part of the
    standard, therefore cannot be deprecated.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Apr 7, 2004
    #9
  10. Kevin Goodsell <> spoke thus:

    > It's true that those headers which are part of the standard and which
    > end in .h are deprecated, but <iostream.h> is not even part of the
    > standard, therefore cannot be deprecated.


    Clearly my answer was deprecated - sorry :)

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Apr 8, 2004
    #10
  11. Tim Johansson

    Jack Klein Guest

    On Wed, 7 Apr 2004 20:35:28 +0000 (UTC), Christopher Benson-Manica
    <> wrote in comp.lang.c++:

    > Tim Johansson <> spoke thus:
    >
    > > #include <iostream.h>

    >
    > It's called <iostream> - the .h headers are deprecated.
    >
    > > #include <string.h>

    >
    > > int main () {
    > > srand(time(0));
    > > int array_length;
    > > int count;
    > > int randm;
    > > char temp[30];
    > > cout << "How many items in array? ";
    > > cin >> array_length;
    > > char items [30][array_length + 1];

    > ^^^^^^^^^^^^
    > I assume this is legal in C++, but I'd love it if a real C++ person
    > stated something authoratative. As an aside, if you're making the
    > array array_length+1 items long, then array_length isn't really, is
    > it?


    No, it is not legal in C++. It is legal in C under the
    not-widely-implemented C99 version of the standard, where arrays with
    automatic storage class can be VLAs (Variable Length Arrays). It is
    also a non-standard extension provided by GNU and perhaps other
    compilers.

    --
    Jack Klein
    Home: http://JK-Technology.Com
    FAQs for
    comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
    comp.lang.c++ http://www.parashift.com/c -faq-lite/
    alt.comp.lang.learn.c-c++
    http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html
     
    Jack Klein, Apr 8, 2004
    #11
  12. Tim Johansson

    Old Wolf Guest

    Christopher Benson-Manica <> wrote:
    > Tim Johansson <> spoke thus:
    >
    > > char items [30][array_length + 1];

    > ^^^^^^^^^^^^
    > I assume this is legal in C++, but I'd love it if a real C++ person
    > stated something authoratative. As an aside, if you're making the
    > array array_length+1 items long, then array_length isn't really, is
    > it?


    Well it isn't the array length anyway: he would have declared an array
    of 30 items, each item of which has length (array_length+1), if the
    syntax were legal.

    > > for (count = 0; count < array_length; count++) {
    > > randm = rand() % array_length;
    > > strcpy (temp[30], items[30][count]);

    >
    > Here's the problem (well, besides that you're using C-style strings at
    > all): strcpy is prototyped as
    >
    > char *strcpy( char *s, const char *t );
    >
    > What is temp[30]? It's a char, of course. And what is
    > items[30][count]? It's a char, too. No wonder it doesn't compile,
    > eh?


    Not to mention that both are undefined behaviour (reading a char
    from past the end of the array). God knows what he was trying to do there.

    > Either read a C book or learn how to use std::strings and std::vectors
    > - I recommend the latter.


    Seeing code like this is what moved me from the "Learn C then C++" camp
    to the "Learn C++ then C" camp. Petec's replacement program is
    excellent.
     
    Old Wolf, Apr 8, 2004
    #12
  13. Kevin, someone should be paying you.

    john
     
    John Harrison, Apr 8, 2004
    #13
  14. "Tim Johansson" <> wrote in message
    news:c51l09$2nosfd$-berlin.de...
    > I'm new to C++, and tried to start making a script that will shuffle an
    > array. Can someone please tell me what's wrong?
    >


    You've been give lots of good advice, but clearly the best advice is to find
    better material for your learning.

    1) Get a good book, one that doesn't say that <iostream.h> is the right
    thing to do. Also one that mentions standard library templates such as
    string and vector (these are what you should be using for this program).

    2) Get a better compiler. The compiler you are using is allowing you to get
    away with illegal code. What sort of way to learn C++ is that? Now I'm
    guessing here but if you are using gcc or g++ then you should compile with
    the -ansi and -pedantic options. This will make your compiler much closer to
    the real C++ language.

    john
     
    John Harrison, Apr 8, 2004
    #14
  15. John Harrison wrote:

    > Kevin, someone should be paying you.
    >
    > john
    >
    >


    Well, I certainly think so. ;) But not for what I'm doing here. I think
    we all do this for basically the same reason: because learning is hard,
    because we want to see the overall quality of programmers improve, and
    because we want to give back to the group that is always here to help us
    when we need it.

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.
     
    Kevin Goodsell, Apr 8, 2004
    #15
  16. Kevin Goodsell <> spoke thus:

    > Well, I certainly think so. ;) But not for what I'm doing here. I think
    > we all do this for basically the same reason: because learning is hard,
    > because we want to see the overall quality of programmers improve, and
    > because we want to give back to the group that is always here to help us
    > when we need it.


    You forgot some reasons: learning is fun, writing elegant code is fun,
    and engaging in arcane pedantry is fun ;)

    --
    Christopher Benson-Manica | I *should* know what I'm talking about - if I
    ataru(at)cyberspace.org | don't, I need to know. Flames welcome.
     
    Christopher Benson-Manica, Apr 8, 2004
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Patrick.O.Ige
    Replies:
    1
    Views:
    2,006
    Patrick.O.Ige
    Jul 2, 2006
  2. spoilsport
    Replies:
    5
    Views:
    3,863
    BartenderSam
    Mar 4, 2004
  3. Java Guy
    Replies:
    1
    Views:
    706
    Manish Pandit
    Oct 15, 2006
  4. lovecreatesbeauty
    Replies:
    1
    Views:
    1,149
    Ian Collins
    May 9, 2006
  5. Perro Flaco

    const char* to char* conversion

    Perro Flaco, Jun 19, 2006, in forum: C++
    Replies:
    34
    Views:
    1,342
    Victor Bazarov
    Jun 21, 2006
Loading...

Share This Page