Thread: For Loop leaves C-String untouched

  1. #1
    Registered User
    Join Date
    Feb 2019
    Posts
    69

    For Loop leaves C-String untouched

    Hey,

    given the following method:


    Code:
    char* timeConversion(char* s)  {    //Input e.g 10:00:00PM, 01:12:55AM
        char* military_time = "00:00:00";
        for(int i = 0; i < 8; i++){
           military_time[i] = s[i];
        }
        if(s[8] == 'P'){
           char hours = 10*(s[0]-50)+(s[1]-50);
           hours += 12;
           char tenner = (hours/10) + 50;
           char onner = hours%10 + 50;
           military_time[0] = tenner;
           military_time[1] = onner;
        }
        return military_time;
    
    }
    Nothing is returned. All the time.

    Given that code:

    Code:
    char* timeConversion(char* s)  {//Input e.g 10:00:00PM, 01:12:55AM
        char* military_time = "00:00:00";
        for(int i = 0; i < 8; i++){
           military_time[i] = s[i];
    
        }
    return military_time;
    The returned value of the array is: "00:00:00". Why?
    I am sure there is a simple explanation.

    Thank you!

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Trying to modify a string literal results in undefined behaviour. You could change the pointer to an array, but then when you return the array, it would be converted to a pointer to its first element... and then the caller would have a pointer to something that no longer exists. You could fix this by declaring the array static, but then the caller becomes responsible for copying over the string as needed.

    Instead of returning a pointer, have a second pointer parameter that points to the first character of an array of char that will hold the result.
    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. #3
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Quote Originally Posted by laserlight View Post
    Trying to modify a string literal results in undefined behaviour.

    Instead of returning a pointer, have a second pointer parameter that points to the first character of an array of char that will hold the result.
    Hey, first of all, thank you for your quick answer.
    Why does this result in undefined behaviour?

    "Instead of returning a pointer, have a second pointer parameter that points to the first character of an array of char that will hold the result."

    I am not allowed to introduce a second parameter.
    Time Conversion | HackerRank

    How do you copy a String then, strcpy?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by SuchtyTV
    Why does this result in undefined behaviour?
    The simple answer is: because the C standard says so. The underlying reason is so that the string literal can be placed in memory that is not to be modified.

    Quote Originally Posted by SuchtyTV
    I am not allowed to introduce a second parameter.
    True, but you are not allowed to modify a string literal either. However, you are allowed to read and follow instructions: "either make the string static or allocate on the heap".

    EDIT:
    Oh wait, I see that they provided two examples. The second example is incorrect, and unfortunately you chose to follow it. Not your fault as it should have been:
    Code:
    char *str = malloc(12);
    or something along those lines. For this particular case though, the static version is likely to be better since competitive programming like hacker rank may not care so much about maintainable code.
    Last edited by laserlight; 05-15-2019 at 03:18 AM.
    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

  5. #5
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    True, but you are not allowed to modify a string literal either. However, you are allowed to read and follow instructions: "either make the string static or allocate on the heap"

    Didn't I?
    Code:
    char* military_time = "00:00:00";

    I changed the code like this:

    Code:
    char* timeConversion(char* s) {    char* military_time = "00:00:00";
        strncpy(military_time, s,8);
        return military_time;
    
    }
    This still returns nothing.
    Last edited by SuchtyTV; 05-15-2019 at 03:19 AM.

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No, you didn't. That declares a pointer that points to the first character of a string literal.
    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

  7. #7
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Quote Originally Posted by laserlight View Post
    No, you didn't. That declares a pointer that points to the first character of a string literal.
    In the examples in the comment of the challenge they give a possibility to do it exactly like this.

    /*
    * Please either make the string static or allocate on the heap. For example,
    * static char str[] = "hello world";
    * return str;
    *
    * OR
    *
    * char* str = "hello world";
    * return str;
    *
    */

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Yes, and the second example is wrong. Ignore it. I have an example of correctly allocating on the heap in my edit to my post #4.
    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

  9. #9
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Alright got it. I will try. Thank you.
    Is allocating like in the incorrect example, a problem with their server? Is my code technically correct? What the reason why my code does not work?

    Thank you.

    Edit: Also this pointer can never be freed? Can it?
    Last edited by SuchtyTV; 05-15-2019 at 03:35 AM.

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    No, the instruction is correct. It is the second example that is wrong, i.e., it isn't actually an example of what you were instructed to do.

    Your code is technically wrong because it attempts to modify a string literal. Doing that results in undefined behaviour. One symptom of undefined behaviour is that no matter how hard you try to modify it, the string remains unmodified. Another possible symptom of undefined behaviour is that your program crashes. Yet another possible symptom of undefined behaviour is that everything works, until the moment that you are demonstrating the program to important people, then Bad Things Happen. So, avoid undefined behaviour.
    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

  11. #11
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Quote Originally Posted by laserlight View Post
    No, the instruction is correct. It is the second example that is wrong, i.e., it isn't actually an example of what you were instructed to do.

    Your code is technically wrong because it attempts to modify a string literal. Doing that results in undefined behaviour. One symptom of undefined behaviour is that no matter how hard you try to modify it, the string remains unmodified. Another possible symptom of undefined behaviour is that your program crashes. Yet another possible symptom of undefined behaviour is that everything works, until the moment that you are demonstrating the program to important people, then Bad Things Happen. So, avoid undefined behaviour.
    Is there a way to properly substitute string literals?

    Code:
    char* timeConversion(char* s) {
        char* military_time = malloc(9*sizeof(char)); //how should i free this space? Does space get freed if the program ends? I thought not.
        military_time = "00:00:00"; //Everything alright until here.
        strncpy(military_time, s,8); // this does not work either
        military_time[8] = '\0'; //this was suggested by a website, I am modifing a string literal. Both ways it does not work.
        return military_time;
    

  12. #12
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Code:
    char* timeConversion(char* s) {
        char* military_time = malloc(sizeof("00:00:00"));
        strcpy(military_time, "00:00:00");
    EDIT:
    Actually, you don't need the strcpy. Aren't you already modifying in the loop in your original code? You don't seem to be using "00:00:00".
    Last edited by laserlight; 05-15-2019 at 03:49 AM.
    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

  13. #13
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Sorry, I feel confused. The problem I seem to have, I need a function

    f: String --> another_String

    I need to copy information from string s, which of course is dynamic. s is bigger in size than the result, also I need to add a ''\0" to the militarytime after I copied. Is there a way to accomplish this?

  14. #14
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Yes, stop this "00:00:00" business and use s to compute how much space you need. For example:
    Code:
    char *military_time = malloc(strlen(s) + 1);
    That said, doesn't "military time" take a specific maximum number of characters? You should be able to pre-determine that.
    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

  15. #15
    Registered User
    Join Date
    Feb 2019
    Posts
    69
    Okay. So you are creating a string which bigger than the actual string. I am unhappy, since we are wasting space here (I always need 8 characters + ''\0"). But it should work, since we all use more than GBs as Ram.
    Then I need to take the first characters of s, modify them and put them into military_time. I am not allowed to modify directly. Is there a method for substitution?

    EDIT: Yes, military string does need a constant amount of chars. However I need a way to copy from biggerString to smallerString with thereby setting '\0' at the end of the smaller string.
    Last edited by SuchtyTV; 05-15-2019 at 04:13 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 11-15-2009, 12:11 PM
  2. leaves on a binary tree
    By drdodirty2002 in forum C++ Programming
    Replies: 7
    Last Post: 11-30-2004, 04:03 AM
  3. Calculates the number of leaves
    By NightWalker in forum C Programming
    Replies: 4
    Last Post: 09-15-2003, 03:02 AM
  4. SDL project leaves trail
    By Shadow12345 in forum Game Programming
    Replies: 6
    Last Post: 05-26-2002, 09:19 AM
  5. my prog leaves fast
    By xlordt in forum C Programming
    Replies: 7
    Last Post: 01-03-2002, 06:29 PM

Tags for this Thread