strcat() Problems

Discussion in 'C++' started by Patrick Coleman, Sep 1, 2003.

  1. Hi,
    I have the following code:

    char request[] = "GET ";
    strcat(request, path); //Path is the path section of a url ie. "/path/test.htm"
    strcat(request, " HTTP/1.1");

    cout<<request<<"\n"; //This outputs "GET /path/test.htm HTTP/1.1" happily

    //Send packet (I know there's no error checking, this is just an example)
    int numbytes;
    numbytes = send(socknum, request, sizeof(request), 0));

    cout<<"Tried to send "<<sizeof(request)<<" bytes, sent "<<numbytes<<" bytes.\n";
    //This line outputs 5 bytes Tried, 5 bytes sent, which is my problem

    The problem with this is that when I check the packet sent (with a packet
    sniffer) the packets only contains "GET " (It should contain
    "GET /path/test.htm HTTP/1.1"). It seems to me that only the variable
    declaration is storing the data properly, and the strcat command just
    'links' that data somehow...(I'm probably wrong, but thats my (vague) idea of the
    situation, anyway)

    How can I get around this? I know if I declare request of a fixed length,
    ie.
    char request[1024] = "GET ";
    strcat(request, path);
    strcat(request, " HTTP/1.1");

    It outputs everything, but request is padded with \0 which confuses the
    other server even more. Besides, if the path is longer than that, it'll
    screw up...

    Thanks for any help in advance,
    Patrick
    Patrick Coleman, Sep 1, 2003
    #1
    1. Advertising

  2. On Tue, 02 Sep 2003 06:17:25 +0800, "Patrick Coleman" <> wrote:

    >I have the following code:
    >
    >char request[] = "GET ";


    Use a std::string, because


    >strcat(request, path); //Path is the path section of a url ie. "/path/test.htm"


    otherwise you're likely to write to arbitrary parts of memory, willy-nilly,
    like you do here


    >strcat(request, " HTTP/1.1");


    and here.


    >cout<<request<<"\n"; //This outputs "GET /path/test.htm HTTP/1.1" happily


    This may or may not "work" depending on the weather situation in Australia.



    >//Send packet (I know there's no error checking, this is just an example)
    >int numbytes;
    >numbytes = send(socknum, request, sizeof(request), 0));


    Use std::string, because otherwise you're likely to use the wrong operators
    and functions, as you do here.
    Alf P. Steinbach, Sep 1, 2003
    #2
    1. Advertising

  3. On Mon, 01 Sep 2003 22:25:50 +0000, Alf P. Steinbach wrote:

    > On Tue, 02 Sep 2003 06:17:25 +0800, "Patrick Coleman" <> wrote:
    >

    <snip>
    > Use std::string, because otherwise you're likely to use the wrong operators
    > and functions, as you do here.


    I have tried using an std::string, with the same results.
    -Patrick
    Patrick Coleman, Sep 1, 2003
    #3
  4. Patrick Coleman

    Christopher Guest

    "Patrick Coleman" <> wrote in message
    news:p...
    > On Mon, 01 Sep 2003 22:25:50 +0000, Alf P. Steinbach wrote:
    >
    > > On Tue, 02 Sep 2003 06:17:25 +0800, "Patrick Coleman"

    <> wrote:
    > >

    > <snip>
    > > Use std::string, because otherwise you're likely to use the wrong

    operators
    > > and functions, as you do here.

    >
    > I have tried using an std::string, with the same results.
    > -Patrick


    You can't use char variable[] like it will magically grow and allocate
    memory by itself. The fact that you said, "besides if the path is longer
    than that, it'll screw up" implies that you need a better data structure,
    one that allocates and releases it's memory by itself. As was said,
    std::string is perfect for the job. If you really gave it a try and got the
    same results I don't think you could have been using the string properly.
    Post the code using std::string and maybe we can help you find where the
    problem is with it. Other than using std::string you will have to make a
    static array big enough to handle any case. Dealing with the null character
    at the end could be done by not sending that byte. I don't know if yer using
    tcp or udp, and both are really not on topic for this newsgroup, but if you
    are using tcp than consider putting a loop around your send function
    getting,checking, and sending each byte from the buffer and exiting on a
    NULL character instead of sending it.
    ,
    Christopher
    Christopher, Sep 2, 2003
    #4
  5. Patrick Coleman

    Frank Xie Guest

    "Patrick Coleman" <> wrote in message news:<>...
    > On Mon, 01 Sep 2003 22:25:50 +0000, Alf P. Steinbach wrote:
    >
    > > On Tue, 02 Sep 2003 06:17:25 +0800, "Patrick Coleman" <> wrote:
    > >

    > <snip>
    > > Use std::string, because otherwise you're likely to use the wrong operators
    > > and functions, as you do here.

    >
    > I have tried using an std::string, with the same results.
    > -Patrick


    char *strcat(char *dest, const char *src) requires dest string must
    have enough space for the result (for both dest and src)
    Frank Xie, Sep 2, 2003
    #5
  6. "Patrick Coleman" <> wrote in message
    news:p...
    > On Mon, 01 Sep 2003 22:25:50 +0000, Alf P. Steinbach wrote:
    >
    > > On Tue, 02 Sep 2003 06:17:25 +0800, "Patrick Coleman"

    <> wrote:
    > >

    > <snip>
    > > Use std::string, because otherwise you're likely to use the wrong

    operators
    > > and functions, as you do here.

    >
    > I have tried using an std::string, with the same results.
    > -Patrick


    Try using std::string *properly* then. You make two big mistakes, not
    allocating memory and misunderstand sizeof. std::string provides safe
    alternatives for both.

    std::string request = "GET ";
    request += path;
    request += " HTTP/1.1";

    cout<<request<<"\n"; //This outputs "GET /path/test.htm HTTP/1.1" happily

    int numbytes;
    numbytes = send(socknum, request.data(), request.size(), 0));

    += instead of strcat, request.size() instead of sizeof(request),
    request.data() to get the char pointer.

    john
    John Harrison, Sep 2, 2003
    #6
  7. Thanks for all the info. I wasnt using std::string properly (as you
    guessed :) - the example clarified things for me. I was doing:

    request = request + path;

    Which is obviously a flashback from my VB days :/
    Thanks again for the info,
    Patrick
    Patrick Coleman, Sep 2, 2003
    #7
  8. Patrick Coleman wrote:
    >
    > Thanks for all the info. I wasnt using std::string properly (as you
    > guessed :) - the example clarified things for me. I was doing:
    >
    > request = request + path;
    >
    > Which is obviously a flashback from my VB days :/


    Nothing wrong with the above.
    Your problem must have been something else

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Sep 2, 2003
    #8
  9. Patrick Coleman

    Stephen Howe Guest

    > Hi,
    > I have the following code:
    >
    > char request[] = "GET ";


    request is a buffer of exactly 5 characters :- 'G', 'E', 'T', ' ', '\0'
    There is _NO_ space for any more characters

    > strcat(request, path); //Path is the path section of a url ie.

    "/path/test.htm"

    ILLEGAL !!! - you are overwriting beyond the end of request[]. request[]
    won't grow in size. You can only do strcat() if you have pre-allocated
    enough space to write the characters in.

    > strcat(request, " HTTP/1.1");


    ILLEGAL !!! - you are overwriting beyond the end of request[], again.

    > cout<<request<<"\n"; //This outputs "GET /path/test.htm HTTP/1.1" happily


    It may well do. You have got away with it. But have no doubt, the above
    strcat's caused problems. Now if you originally said

    char request[256] = "GET "; // note the number 256

    providing your total buffer size was less than 256 characters (including the
    terminating '\0'), your strcat's would work.

    > cout<<"Tried to send "<<sizeof(request)<<" bytes, sent "<<numbytes<<"

    bytes.\n";
    > //This line outputs 5 bytes Tried, 5 bytes sent, which is my problem


    Because sizeof() is the wrong thing. If you

    char request[256] = "GET "; // note the number 256

    you don't want to output 256 (what sizeof would return) do you when only
    send, sy 40 characters? It should be

    cout<<"Tried to send "<<strlen(request)<<" bytes, sent "<<numbytes<<"
    bytes.\n";

    > How can I get around this? I know if I declare request of a fixed length,
    > ie.
    > char request[1024] = "GET ";
    > strcat(request, path);
    > strcat(request, " HTTP/1.1");


    Which is correct. You provide enough space.

    > It outputs everything, but request is padded with \0 which confuses the
    > other server even more. Besides, if the path is longer than that, it'll
    > screw up...


    These use strlen() not sizeof(). You are only using part of the buffer, not
    all of it. sizeof returns the total size of the buffer.

    Stephen Howe





    >
    > Thanks for any help in advance,
    > Patrick
    >
    Stephen Howe, Sep 2, 2003
    #9
  10. Patrick Coleman

    Stephen Howe Guest

    > I have tried using an std::string, with the same results.
    > -Patrick


    Show us your code. You are probably using std::string incorrectly.

    Stephen Howe
    Stephen Howe, Sep 2, 2003
    #10
  11. Patrick Coleman

    llewelly Guest

    "Patrick Coleman" <> writes:

    > Thanks for all the info. I wasnt using std::string properly (as you
    > guessed :) - the example clarified things for me. I was doing:
    >
    > request = request + path;
    > Which is obviously a flashback from my VB days :/

    [snip]

    ?
    I'm confused. This:

    int main()
    {
    std::string request;
    std::string path;
    request= request + path;
    }

    is a perfectly valid use of string in C++.
    More, in VB, IIRC, one concatenates strings with '&', not '+'.
    llewelly, Sep 2, 2003
    #11
  12. On Tue, 02 Sep 2003 11:02:46 -0600, llewelly wrote:

    > "Patrick Coleman" <> writes:
    >
    >> Thanks for all the info. I wasnt using std::string properly (as you
    >> guessed :) - the example clarified things for me. I was doing:
    >>
    >> request = request + path;
    >> Which is obviously a flashback from my VB days :/

    > [snip]
    >
    > ?
    > I'm confused. This:
    >
    > int main()
    > {
    > std::string request;
    > std::string path;
    > request= request + path;
    > }
    >
    > is a perfectly valid use of string in C++.
    > More, in VB, IIRC, one concatenates strings with '&', not '+'.


    Hmm. When I used the code request = request + path;, I'm pretty sure that
    I got the same problem that I started out with, that it would only send
    "GET ". This is what I used:

    request = "GET " + path + " HTTP/1.1";
    Is that valid?
    Patrick Coleman, Sep 8, 2003
    #12
  13. Patrick Coleman wrote:
    >
    > On Tue, 02 Sep 2003 11:02:46 -0600, llewelly wrote:
    >
    > > "Patrick Coleman" <> writes:
    > >
    > >> Thanks for all the info. I wasnt using std::string properly (as you
    > >> guessed :) - the example clarified things for me. I was doing:
    > >>
    > >> request = request + path;
    > >> Which is obviously a flashback from my VB days :/

    > > [snip]
    > >
    > > ?
    > > I'm confused. This:
    > >
    > > int main()
    > > {
    > > std::string request;
    > > std::string path;
    > > request= request + path;
    > > }
    > >
    > > is a perfectly valid use of string in C++.
    > > More, in VB, IIRC, one concatenates strings with '&', not '+'.

    >
    > Hmm. When I used the code request = request + path;, I'm pretty sure that
    > I got the same problem that I started out with, that it would only send
    > "GET ". This is what I used:
    >
    > request = "GET " + path + " HTTP/1.1";
    > Is that valid?


    Yep.
    Your problem might have been when you actually sent the string.
    If I remember correctly the code snippet you posted used 'sizeof'
    to determine the string length, which of course is nonsense.
    sizeof is evaluated at compile time, so how can it detect the
    length of something growing and shrinking during runtime?

    --
    Karl Heinz Buchegger
    Karl Heinz Buchegger, Sep 9, 2003
    #13
  14. Patrick Coleman

    llewelly Guest

    "Patrick Coleman" <> writes:

    > On Tue, 02 Sep 2003 11:02:46 -0600, llewelly wrote:
    >
    >> "Patrick Coleman" <> writes:
    >>
    >>> Thanks for all the info. I wasnt using std::string properly (as you
    >>> guessed :) - the example clarified things for me. I was doing:
    >>>
    >>> request = request + path;
    >>> Which is obviously a flashback from my VB days :/

    >> [snip]
    >>
    >> ?
    >> I'm confused. This:
    >>
    >> int main()
    >> {
    >> std::string request;
    >> std::string path;
    >> request= request + path;
    >> }
    >>
    >> is a perfectly valid use of string in C++.
    >> More, in VB, IIRC, one concatenates strings with '&', not '+'.

    >
    > Hmm. When I used the code request = request + path;, I'm pretty sure that
    > I got the same problem that I started out with, that it would only send
    > "GET ". This is what I used:
    >
    > request = "GET " + path + " HTTP/1.1";
    > Is that valid?


    Let's try that again. I wrote:

    #include<string>
    #include<iostream>
    #include<ostream>

    int main()
    {
    std::string request;
    std::string path= "/home/llewelly/cc_moderated/adl.cc";
    char const* path2= "/home/llewelly/cc_moderated/adl.cc";
    request = "GET " + path + " HTTP/1.1";
    //request = "GET " + path2 + " HTTP/1.1"; //Compile-time error.
    std::cout << request << std::endl;
    }

    and when I ran it, I got:

    GET /home/llewelly/cc_moderated/adl.cc HTTP/1.1

    If I uncomment the line using path2 (which is a char const*, *not* a
    std::string), I get:

    str4.cc: In function `int main()':
    str4.cc:9: error: invalid operands of types `const char[5]' and
    `const char*' to binary `operator+'


    as a compile time error.

    Does that help?

    When you concatenate strings using +, one of the two strings must be
    an std::string. When you chain several concatenations together,
    one of the first two must be an std::string .
    llewelly, Sep 9, 2003
    #14
  15. Patrick Coleman

    Ron Natalie Guest

    "llewelly" <> wrote in message news:...

    > request = "GET " + path + " HTTP/1.1";
    > //request = "GET " + path2 + " HTTP/1.1"; //Compile-time error.


    The + operator can't be overloaded on pointers alone. One operand must be
    of type string (and so will the result0. The second would have worked if you
    had done:
    request = "GET" + string(path2) + " HTTP/1.1";
    Forces the middle value to string type.
    Ron Natalie, Sep 9, 2003
    #15
    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. Nicholas

    Using strcat

    Nicholas, Sep 9, 2003, in forum: C Programming
    Replies:
    10
    Views:
    859
    Jirka Klaue
    Sep 12, 2003
  2. Pieter Droogendijk

    alleged mis-form with strcat

    Pieter Droogendijk, Sep 12, 2003, in forum: C Programming
    Replies:
    6
    Views:
    442
    LibraryUser
    Sep 13, 2003
  3. Ian Stanley

    strcat problem

    Ian Stanley, Sep 12, 2003, in forum: C Programming
    Replies:
    5
    Views:
    3,594
    Irrwahn Grausewitz
    Sep 13, 2003
  4. Ian Stanley

    strcat problem again

    Ian Stanley, Sep 17, 2003, in forum: C Programming
    Replies:
    18
    Views:
    693
    Martijn Lievaart
    Sep 22, 2003
  5. JC

    strcpy and strcat problem

    JC, Sep 26, 2003, in forum: C Programming
    Replies:
    23
    Views:
    1,892
    Robert B. Clark
    Sep 29, 2003
Loading...

Share This Page