Thread: Modify string in function

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    But why would you want to?
    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.

  2. #17
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by King Mir
    You can also do this:
    It would be incorrect since a pointer to an array is not convertible to a pointer to a pointer. You would need to have a pointer in main point to the first element of buf, and then pass the address of that pointer... or just change the function signature to pass the pointer by reference.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #18
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    You're right. I had it like that first, then thought it wouldn't be needed. Fixed it now.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  4. #19
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    Thanks for the kind help.
    I worked it out with this solution:
    Reference to an array: int (&arr)[mysize];

    I wanted to avoid dynamic allocation because I was having trouble freeing it, it kept on crashing even after I copied the allocated buffer to a static buffer.
    Using Windows 10 with Code Blocks and MingW.

  5. #20
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Ducky
    I worked it out with this solution:
    Reference to an array: int (&arr)[mysize];
    Why not post your working code?

    Personally, I don't often see references to arrays being used, and I don't see how it would solve your problem in this thread since you are doing pointer arithmetic. In fact, if I'm pressed for a good use of a reference to an array, I would probably give the one where it is used to return sizeof the array from a function template.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #21
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    You are right I didnt need the reference after all.
    The problem was before that when I passed a dynamic buffer to the function I didnt get back the data modified in the function.
    But with a static buffer I dont seem to need to pass by reference.

    Maybe you can find some simplification to it. Thanks.

    Code:
    int main()
    {
    
       char buf[260];
       ReceiveDataWithHeader(Socket, Buf);
       cout << "iReceived " <<  Buf  << endl;
    
    }
    // size of data in header
    int ReceiveDataWithHeader(SOCKET Socket, char Buf2[260])
    {
        bool iGetSize = 1;
        short iReceived = 0;
        unsigned long DataSize=0, TotalSize=1;
        unsigned long Total=0, Digits=0;
        char * pch;
        char * Buf = Buf2;
    
        while(TotalSize)
        {
            iReceived = recv(Socket, Buf, 32, 0);
            cout << "iReceived " <<  Buf  << endl;
            cout << "iReceived " <<  iReceived  << endl;
            if(iReceived > 0)
            {
                if(iGetSize)
                    Total += iReceived;
                else
                    TotalSize -= iReceived;
                if(iGetSize)
                {
                    pch = strchr(Buf,'$');
                    // if recieved DataSize
                    if (pch!=NULL)
                    {
                        pch[0] = '\0';
                        // got DataSize
                        DataSize=atoi(Buf);
                        cout << "DataSize " <<  DataSize  << endl;
    
                        
                        Digits = GetNumberOfDigits(DataSize);
                        cout << "Digits " <<  Digits  << endl;
                        // NumberOfDigits + $  + DataSize
                        TotalSize =  Digits + 1  + DataSize;
    
                        cout << "TotalSize " <<  TotalSize  << endl;
                        // substruct all that we got until now
                        TotalSize -= Total;
    
                        // remove 0
                        pch[0] = '$';
                        // dont come here anymore
                        iGetSize = 0;
                    }
                }
    
                Buf += iReceived;
                cout << "TotalSize " <<  TotalSize  << endl;
    
            }
            else if ( iReceived == 0 )
            {
                printf("ReceiveDataWithHeader Connection closed\n");
                return 1;
            }
            else
            {
                ReportError("ReceiveDataWithHeader");
                return 1;
            }
        }
    
        strcpy(Buf, "\0");
        Buf -= DataSize; // go back to the beginning
        strcpy(Buf2, Buf);
        return 0;
    }
    Last edited by Ducky; 06-18-2012 at 01:53 PM.
    Using Windows 10 with Code Blocks and MingW.

  7. #22
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    I think you could still work with the string class. You can make a string out of the data in buf and the length of the data after the recv() call. If you have to call any other networking functions with C-strings as arguments, just call string::copy() beforehand. That's about as simple as it becomes.

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Buf2 is already a pointer, so you do not need Buf. You should also pass the buffer by reference, so you can query its real size to avoid buffer overflows.
    I do not know which parameter to recv that is the buf size, but make sure buf can hold at least that much!
    Either use sizeof in recv or use static asserts to ensure buffer size is greater than what you pass to recv.
    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.

  9. #24
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> You should also pass the buffer by reference, so you can query its real size to avoid buffer overflows.

    Whereas I just rely on constants and calculation where possible. You could pass in the size of the buffer as another argument. The method that you recommend requires templates to make the buffer flexible in size, it also is completely impossible to use with dynamic memory, so in more general situations it is impractical. I don't like those kinds of problems. On the other hand, I can shrug it off as a garbage in, garbage out kind of issue.

    >> I do not know which parameter to recv that is the buf size, but make sure buf can hold at least that much!

    Then perhaps you shouldn't comment. I know it's not a C standard function, so you don't know it but in this case his usage is more than fine.
    Last edited by whiteflags; 06-18-2012 at 05:06 PM.

  10. #25
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    @Elysia
    Buf2 is already a pointer, so you do not need Buf.

    Buf2 is an array not a pointer hence I cant have pointer arithmetics on it. Thats why I added char * Buf.

    whiteflags I think you could still work with the string class.

    I could and I started to transform the code but im not sure that it would result in a smaller and simpler code. Not worth the hassle.
    I dont wanna go there but C++ functions aren't any handier than the C versions.
    Nothing but to split the buffer into three tokens I would need three times more code than what I have already.
    You can prove me wrong inside my code if you feel like it though.
    Using Windows 10 with Code Blocks and MingW.

  11. #26
    Registered User
    Join Date
    Dec 2007
    Posts
    932
    @Elysia Buf2 is already a pointer, so you do not need Buf.

    Buf2 is an array not a pointer hence I cant have pointer arithmetics on it. Thats why I added char * Buf.

    @whiteflags I think you could still work with the string class.

    I could and I started to transform the code but im not sure that it would result in a smaller and simpler code. Not worth the hassle.
    I dont wanna go there but C++ functions aren't any handier than the C versions.
    Nothing but to split the buffer into three tokens I would need three times more code than what I have already.
    You can prove me wrong inside my code if you feel like it though.
    Using Windows 10 with Code Blocks and MingW.

  12. #27
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> I dont wanna go there but C++ functions aren't any handier than the C versions.

    You won't offend me so easily.

    >> Nothing but to split the buffer into three tokens I would need three times more code than what I have already.

    It's late so don't try to plug this in.

    Code:
    token = buffer.substr(0,buffer.find('$')); 
    // This is just the first pass, you can track the starting point with a variable
    // In fact, you could put the find step on an earlier line and make that easier.
    
    dataSize = atoi(token.c_str());
    // Use like normal
    // buffer is not changed by this code
    From what I can see, this services your needs. You could make it more C++ like but in controlled environment, I can understand the opinion that anything more is fluff.

    I think I'm ready for bed.
    Last edited by whiteflags; 06-19-2012 at 12:48 AM. Reason: sleep induced mistakes

  13. #28
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by whiteflags View Post
    Whereas I just rely on constants and calculation where possible. You could pass in the size of the buffer as another argument. The method that you recommend requires templates to make the buffer flexible in size, it also is completely impossible to use with dynamic memory, so in more general situations it is impractical. I don't like those kinds of problems. On the other hand, I can shrug it off as a garbage in, garbage out kind of issue.
    If you use dynamic memory, use std::vector. Then use its .size() member.

    Quote Originally Posted by whiteflags View Post
    Then perhaps you shouldn't comment. I know it's not a C standard function, so you don't know it but in this case his usage is more than fine.
    I didn't say it was not fine. You missed my point. The point is that the size is hard coded and the size of the buffer is hard coded. That is just ripe for problems and errors.
    Imagine some day when Ducky increases the recv bytes arg to some higher number and some other day decides that the buf is too big.
    Heck, just imagine having some big buffer and multiple functions using it. It's just bound to be some day when the size of the buffer may be decreased while the buffer size params in the recv calls are the same, or the other way around, that the buffer is the same, but the recv buf size parameter is increased.
    That's a buffer overflow. If you're lucky, it will crash. If you're unlucky, you won't notice it.
    So the best thing to do is to get the compiler to help us catch such a regression at compile time.
    That's why I'm telling these things. You can do it multiple ways, just make sure you do it.

    Quote Originally Posted by Ducky View Post
    Buf2 is an array not a pointer hence I cant have pointer arithmetics on it. Thats why I added char * Buf.
    I know you want to be right, but you aren't. Buf2 is a pointer.

    Code:
    #include <iostream>
    #include <typeinfo>
    
    void foo(char buf[256])
    {
    	std::cout << "foo: buf[256] type: " << typeid(buf).name() << "\n";
    }
    
    int main()
    {
    	char buf[256];
    	std::cout << "main: buf[256] type: " << typeid(buf).name() << "\n";
    	foo(buf);
    	return 0;
    }
    Output:
    main: buf[256] type: char [256]
    foo: buf[256] type: char *

    Besides, pointer arithmetic work on (C-)arrays, too.
    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.

  14. #29
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    >> If you use dynamic memory, use std::vector. Then use its .size() member.

    Which is irrelevant.

    >> That's a buffer overflow. If you're lucky, it will crash. If you're unlucky, you won't notice it.
    >> So the best thing to do is to get the compiler to help us catch such a regression at compile time.

    How do you know what's best? You could debug it like a normal person would when they change their own code. C++ is not one of those happy languages where if it compiles it automatically works. In fact I don't think there is a language like that. You still have to care about what happens in run time no matter what.

  15. #30
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by whiteflags View Post
    >> If you use dynamic memory, use std::vector. Then use its .size() member.

    Which is irrelevant.
    Explain HOW that's irrelevant.

    How do you know what's best? You could debug it like a normal person would when they change their own code. C++ is not one of those happy languages where if it compiles it automatically works. In fact I don't think there is a language like that. You still have to care about what happens in run time no matter what.
    Debug the code? Are you serious? That is a ridiculous argument.
    Debugging isn't meant to make sure the code works. It's meant to FIND what causes the bugs that prevents the coding from working.
    Regression testing makes sure the code works. This is part of regression testing.
    It also creates fewer bugs, and it decreases the likelihood of bugs escaping notice.
    It does not, however, mean that you should rely ONLY on this. This is meant to be a tool to complement your arsenal, not replace it.
    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.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. modify function pass it array
    By a.mlw.walker in forum C Programming
    Replies: 12
    Last Post: 08-01-2011, 04:03 AM
  2. Replies: 15
    Last Post: 05-11-2011, 05:06 PM
  3. how to modify strcmp function
    By asteroid1122 in forum C Programming
    Replies: 6
    Last Post: 08-23-2009, 12:24 AM
  4. modify pointer to a string/character constant.
    By xsouldeath in forum C Programming
    Replies: 12
    Last Post: 10-03-2007, 02:41 AM
  5. modify has function from string parameter to templates...
    By rusty0412 in forum C++ Programming
    Replies: 2
    Last Post: 01-13-2005, 08:02 PM