Thread: Copying strings, all or nothing?

  1. #1
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877

    Copying strings, all or nothing?

    My goal is to copy only the elements of string2 that are equal to string 1 into a new string. I tested this idea with an array of integers and it worked, but didn't work for the strings. My question is: Am I missing something that would make this idea possible?

    Code:
    #include<stdio.h>
    main()
    {
        int scan1;
        char arr1[40] ;
        char arr2[40] ;
        char arr3[40] = {'_',.....,'_'}; /*for sake of brevity with post*/
    
        printf("line1:");
        fgets(arr1,40,stdin);
    
        printf("line2:");
        fgets(arr2,40,stdin);
    
        scan1=0;
    
        /**If arr1 & arr2 are equal, copy parts of arr2 that
        equal arr1 into arr3, if not equal leave those elements of arr3
        alone**/
    
        while(arr1[scan1]!= '\0'){
            arr3[scan1]=(arr2[scan1]==arr1[scan1]) ? arr2[scan1] : arr3[scan1];
            ++scan1;
        }
    
        arr3[scan1]='\0'; /**adding null after copy**/
    
        printf("%s", arr3);
    
        return 0;
        }

    Expected input/output:

    string1:"HELLO"
    string2:"L"
    string3:"__LL_"

    Actual input output:

    string1:"HELLO"
    string2:"L"
    string3:"_____"

    or

    string1:"HELLO"
    string2:"HELLO"
    string3"HELLO"

    String 3 wants it all, or nothing at all.

    Thank you for your time, Alpo.
    Last edited by Alpo; 04-14-2014 at 11:04 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Alpo
    My goal is to copy only the elements of string2 that are equal to string 1 into a new string.
    Your goal does not make sense: an element of string 2 would be a char, therefore, no element of string 2 can be equal to string 1.

    Perhaps you want to copy the elements of string 1 that can be found in string 2 into a new string? If so, your code needs to do more than just compare elements pairwise: you would need to loop over string 2 to check whether the current element of string 1 can be found in it.
    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
    Nov 2012
    Posts
    1,393
    I would recommend rephrasing the part inside your while loop into something less verbose. Try explaining what you're doing there in English step by step, make sure its correct, then rewrite it back to C.

  4. #4
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Basically if the any char in string 2 is equal to a char in string 1, copy only that char from string 2 into string 3, but else wise leave string 3 chars alone. It works on this int array:

    Code:
     #include<stdio.h>
     main()
     {
        int array []={3,1,3,7,5,6,3,7,8,1};
         int array2[]={3,1,3,7,5,6,3,7,7,1};
         int array3[10]={0};
        int scan1, go;
         scan1=0;
        while( scan1 < 10 ){
             array3[scan1]=(array[scan1]==array2[scan1]) ? array2[scan1] : array3[scan1];
            ++scan1;
         }
        for (go=0; go<=9; ++go){
            printf("%d", array3[go]);
        }
        return 0;
    }
    array 3=0,...,0 (before copy)

    array=3,1,3,7,5,6,3,7,8,1

    array2=3,1,3,7,5,6,3,7,7,1 (changed 9th element)

    array3=3,1,3,7,5,6,3,7,0,1 (after copy)
    Last edited by Alpo; 04-14-2014 at 11:58 AM.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Alpo
    It works on this int array:
    Here's proof that it does not work:
    Code:
    #include<stdio.h>
    
    int main(void)
    {
        int array [] = {3, 1, 3, 7, 5, 6, 3, 7, 8, 1};
        int array2[] = {3};
        int array3[10] = {0};
        int scan1, go;
        scan1 = 0;
        while (scan1 < 10 ) {
            array3[scan1]=(array[scan1]==array2[scan1]) ? array2[scan1] : array3[scan1];
            ++scan1;
        }
    
        for (go = 0; go <= 9; ++go) {
            printf("%d", array3[go]);
        }
        return 0;
    }
    I get the output:
    Code:
    3000000000
    instead of the expected:
    Code:
    3030003000
    EDIT:
    Actually, this is confusing. Look at what you wrote: "if the any char in string 2 is equal to a char in string 1, copy only that char from string 2 into string 3". Now, look at what you wrote:
    Expected input/output:

    string1:"HELLO"
    string2:"L"
    string3:"__LL_"
    There is only one char in string2, hence only that char can possibly be copied, so your expected output must be wrong... unless you're mixing up string1 and string2. You need to be absolutely clear.
    Last edited by laserlight; 04-14-2014 at 12:09 PM.
    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. #6
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    @ LaserLight, the first output was expected, only elements of array2 that match array are suppose to be copied, therefor if only a 3 matches, only a 3 is copied, the rest of array 3 should equal what it did before any copying took place.

    Therefor

    array = 1,2,3,4
    array2= 1,3,2,4

    array 3 should output= 1,0,0,4

    I just don't understand why it doesn't work on char strings?

    Good point Laserlight, the L's should have been in the same place. Let me go check it. Thanks.
    Last edited by Alpo; 04-14-2014 at 12:15 PM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Alpo
    @ LaserLight, the first output was expected, only elements of array2 that match array are suppose to be copied, therefor if only a 3 matches, only a 3 is copied, the rest of array 3 should equal what it did before any copying took place.
    Let's consider:
    Code:
    int array [] = {3, 1, 3, 7, 5, 6, 3, 7, 8, 1};
    int array2[] = {6};
    What is the expected output?

    What I am trying to do is to produce an example input for the integer array version that corresponds to your example input for the string version that you say is wrong, in order to demonstrate to you that your algorithm is wrong (or right, as the case may be).
    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

  8. #8
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    SUCCESS!!! OMG, thank you laserlight.

    The expected output would be all 0's on array3 in your example. Since there are no matchs.

    Char array1:HELLO
    Char array2:**LL*

    Char array3(output):__LL_

    I just wasn't matching the correct positions. Seriously thanks.
    Last edited by Alpo; 04-14-2014 at 12:20 PM.

  9. #9
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Quote Originally Posted by Alpo View Post
    SUCCESS!!! OMG, thank you laserlight.

    The expected output would be all 0's on array3 in your example. Since there are no matchs.
    But there is a match (6). That's the point.

    Let's look at the program in your first post. You're looking at the same index value of each array for comparison.

    Code:
    array1: [H ][E ][L ][L ][O ][\0]
    array2: [L ][\0][  ][  ][  ][  ]
    So first you compare the first element of each array. 'H' != 'L', so nothing is copied. Then you look at the second element of each array; 'E' != '\0', so nothing is copied. When you get to the third element, you don't even know what is at array2[2].

    Based on this, doesn't it seem like one variable for tracking array elements might not be enough?

  10. #10
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Oh, ok, I see what you guys were saying now. I like the idea of checking all points for the variable, but I might need time to think on it. Sorry for being so confusing, I didn't realize what was going wrong.

  11. #11
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    No need to be sorry, it's all part of the learning process. Thinking on it is a good idea - for some people, scribbling these things on paper give good insight to the logic needed to implement such ideas. Heck, I have a few sheets of scrap paper on my desk right now with array diagrams I drew out to aid in developing an algorithm.

  12. #12
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    YES!!! Thanks for your hints Matticus. It finds the elements anywhere now, and I added a tolower function to make it easier.
    Code:
    #include<stdio.h>
    char lower(char tolow[], int size)
    {
        int go;
        for (go=0; go<size; ++go){
            tolow[go]=(tolow[go]>='A' && tolow[go]<='Z') ? tolow[go]  +=32 : tolow[go];
        }
     return tolow[go];
    }
    main()
    {
        int scan1, scan2;
        char arr1[40] ;
        char arr2[40] ;
        char arr3[40] = {'_','_',...,'_'};
        printf("line1:");
        fgets(arr1,40,stdin);
        lower(arr1, 40);
        printf("line2:");
        fgets(arr2,40,stdin);
        scan1=0;
        scan2=0;
        /**If arr1 & arr2 are equal, copy parts of arr2 that
        equal arr1 into arr3, if not equal leave those elements of arr3
        alone**/
        while(arr1[scan1]!= '\0'  && arr2[scan2] !='\0'){
            arr3[scan1]=(arr2[scan2]==arr1[scan1]) ? arr2[scan2] : arr3[scan1];
            scan2=(arr2[scan2]!=arr1[scan2])? scan2++ : scan2;
            ++scan1;
        }
        arr3[scan1]='\0'; /**adding null after copy**/
    
            printf("%s", arr3);
     
        return 0;
        }
    Last edited by Alpo; 04-14-2014 at 01:30 PM.

  13. #13
    Registered User
    Join Date
    Jun 2011
    Posts
    4,513
    Well done! Looks pretty good at a quick glance - I'm currently focused on something at work, so I didn't give it a thorough review. However, a few things caught my attention:

    - There is a standard function "tolower()" in <ctype.h> that can convert to lowercase in a more portable manner
    - You should set "arr2" to lowercase as well, so you have consistency during comparison
    - Rather than using the magic number 40, you should #define a named constant for your array lengths
    - While I see you're fond of the ternary conditional operator ( ?: ), it might be making some parts of your program more difficult to reason. More importantly, line 28 could also potentially result in undefined behavior.

  14. #14
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Quote Originally Posted by Alpo View Post
    ... I might need time to think on it.
    That's the most encouraging thing I've heard from a new poster in a long time! :-)

    Usually we have to tell people to do that.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help with copying strings
    By eddieL91 in forum C Programming
    Replies: 5
    Last Post: 04-10-2012, 11:53 AM
  2. K&r 1-17 copying strings
    By AaronP in forum C Programming
    Replies: 4
    Last Post: 11-18-2011, 11:28 PM
  3. Need help copying files into strings???
    By patso in forum C Programming
    Replies: 5
    Last Post: 08-18-2010, 11:22 PM
  4. Problems with copying strings
    By Veneficvs in forum C++ Programming
    Replies: 7
    Last Post: 04-27-2010, 07:40 AM
  5. Copying into an array of strings
    By mettle in forum C Programming
    Replies: 5
    Last Post: 06-14-2006, 02:18 PM

Tags for this Thread