strncmp

Discussion in 'Mac Programming' started by dougphd, May 29, 2016.

  1. dougphd, May 29, 2016
    Last edited by a moderator: May 29, 2016

    dougphd macrumors member

    Joined:
    Apr 28, 2016
    #1
    Code:
    /
       i = 0; k = 0;
    for (j = 0; j < num ; )
    {
       printf("j %d %d %d %s %s\n",j, i, k, etf1[i].date,etf2[k].date);
      while((comp = strncmp(etf1[i].date,etf2[k].date,8)!= 0))
       {
    l = 0; m = 0;
    printf("comp %d\n", comp);
        if (comp > 0)
          { //printf("here2\n");
              m++;
                i++;
                printf("2 %d %d %d %s %s\n",j, i, k, etf1[i].date,etf2[k].date);
           }
         elseif (comp < 0)
           {
             l++;
             k++;
             printf("1 %d %d %d %s %s\n",j, i, k, etf1[i].date,etf2[k].date);
           }
       }
      if (comp == 0)
      {
       i++;
       k++;
       j++;
       }
       elseif (l > m)
       {
        j = j + m;
       }
       else
       {
        j = j + l;
       }
    }
    /
    I have two list of dates etf1[*].date and etf2[*].date The lists do not have the same dates and the code is meant to find the matching dates. You can see when the date in the first date column begins to lags, the code goes to the next date. However when date column two lags, the value of strncmp () doesn't become negative. What gives? stupid error? Not understanding how strncmp works? Confused.

    Code:
    next date 20050609 20050609
    next date 20050610 20050610
    next date 20050613 20050613
    next date 20050614 20050615
    comp 1
    adjustment 20050615 20050615
    next date 20050616 20050616
    next date 20050617 20050617
    next date 20050620 20050620
    next date 20050621 20050623
    comp 1
    adjustment 20050622 20050623
    comp 1
    adjustment 20050623 20050623
    next date 20050624 20050624
    next date 20050627 20050627
    next date 20050628 20050628
    next date 20050630 20050629
    comp 1
    adjustment 20050701 20050629
    comp 1
    adjustment 20050705 20050629
    comp 1
    adjustment 20050706 20050629
     
  2. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #2
    1. Show the declaration of the 'comp' variable.
    What type is it?

    2. The posted output doesn't match the posted code.
    For example, the word "adjustment" appears in the output, but nowhere in the posted code. Likewise with "next date".
    As another example, none of the printf's showing the values of i, j, k, etc. from within the loop have been posted. The only printf that does seem to appear in the output is "comp 1".

    3. The posted code fragment is impractically small to make into a test case.
    It's not impossible, just pointless. Yes, it's possible to guess at all the variable types, write a bunch of new code to parse data from a file (or use static initializers), then finally examine the actual printf'ed output.

    However, it would be far simpler if you just posted the complete actual unedited output from running the code you posted. In particular, being able to see the indexes i, k, etc. from the failing case will likely be informative.

    I assume you either have the output or can easily make it, because you've posted code that should produce it.
     
  3. dougphd, May 29, 2016
    Last edited by a moderator: May 29, 2016

    dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #3
    Code:
    typedef struct sauce
    
    {
        char date[10];
        float sauce;
        float open;
        int index;
    } pesto;
    
    pesto * make_instrument(pesto *etf1, pesto *etf2, int num)
    
    {
      int comp,i,j,k, l , m;
      pesto *instrument;
      instrument = (pesto*)calloc(days_of_data, sizeof(*instrument));
      i = 0; k = 0;
      for (j = 0; j < num ; )
      {
       //The next date in each file
       printf("next date i %d j %d k %d %s %s\n",i,j,k ,etf1[i].date,etf2[k].date);
       while((comp = strncmp(etf1[i].date,etf2[k].date,8)!= 0))
      {
           l = 0; m = 0;
           printf("comp %d\n", comp);
           if (comp > 0)
           {
          m++;
           i++;
           // if comp is greater than zero, the dates after increasing the i index
                printf("adjustment comp > 0 i %d j %d k %d  %s %s\n",i,j, k, etf1[i].date,etf2[k].date);
            }
            elseif (comp < 0)
           {
             l++;
             k++;
           // if comp is less than zero, the dates after increasing the k index
             printf("adjustment comp < 0 %d j %d k %d  %s %s\n",i, j, k, etf1[i].date,etf2[k].date);
            }
          }
        if (comp == 0)
        {
         i++;
         k++;
         j++;
        }
        elseif (l > m)
        {
        j = j + m;
        }
        else
       {
        j = j + l;
        }
      }
      // nothing has been assigned to instrument yet
        return(instrument);
    };
    
    

    A section of the output showing aligned dates; misaligned dates that the code corrects; and the final misaligned dates where the code fails. Ignore the b's
    Code:
    
    [B]next date i 2626 j 2586 k 2586 20050608 20050608[/B]
    
    [B]next date i 2627 j 2587 k 2587 20050609 20050609[/B]
    
    [B]next date i 2628 j 2588 k 2588 20050610 20050610[/B]
    
    [B]next date i 2629 j 2589 k 2589 20050613 20050613[/B]
    
    [B]next date i 2630 j 2590 k 2590 20050614 20050615[/B]
    
    [B]comp 1[/B]
    
    [B]adjustment comp > 0 i 2631 j 2590 k 2590  20050615 20050615[/B]
    
    [B]next date i 2632 j 2591 k 2591 20050616 20050616[/B]
    
    [B]next date i 2633 j 2592 k 2592 20050617 20050617[/B]
    
    [B]next date i 2634 j 2593 k 2593 20050620 20050620[/B]
    
    [B]next date i 2635 j 2594 k 2594 20050621 20050623[/B]
    
    [B]comp 1[/B]
    
    [B]adjustment comp > 0 i 2636 j 2594 k 2594  20050622 20050623[/B]
    
    [B]comp 1[/B]
    
    [B]adjustment comp > 0 i 2637 j 2594 k 2594  20050623 20050623[/B]
    
    [B]next date i 2638 j 2595 k 2595 20050624 20050624[/B]
    
    [B]next date i 2639 j 2596 k 2596 20050627 20050627[/B]
    
    [B]next date i 2640 j 2597 k 2597 20050628 20050628[/B]
    
    [B]next date i 2641 j 2598 k 2598 20050630 20050629[/B]
    
    [B]comp 1
    adjustment comp > 0 i 2642 j 2598 k 2598  20050701 20050629[/B]
    FAILURE HERE.  BOTH DATES SHOULD BE 20050603 20050630
    [B]comp 1[/B]
    
    [B]adjustment comp > 0 i 2643 j 2598 k 2598  20050705 20050629
    
     
  4. chown33, May 29, 2016
    Last edited: May 29, 2016

    chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #4
    This is the first non-matching output:
    Code:
    next date i 2630 j 2590 k 2590 20050614 20050615
    comp 1
    The code that produces the first line is this:
    Code:
       printf("next date i %d j %d k %d %s %s\n",i,j,k ,etf1[i].date,etf2[k].date);
    
    So 20050614 is from etf1, and 20050615 is from etf2.

    Next is this code:
    Code:
       while((comp = strncmp(etf1[i].date,etf2[k].date,8)!= 0))
    
    The function's description says this:

    The strcmp() and strncmp() return an integer greater than, equal to, or
    less than 0, according as the string s1 is greater than, equal to, or
    less than the string s2. The comparison is done using unsigned charac-
    ters, so that `\200' is greater than `\0'.
    Given the args to the function and this description, exactly what value should we expect to have returned from strncmp()?

    Lexically speaking, the 20050614 is less than the 20050615, so we should expect an integer less than 0.

    Unfortunately, that's not what the subsequent output tells us we got. It outputs 1 (a number greater than 0), which seems to signify the 1st string is GREATER than the 2nd string. This is not what's expected, given the output from printf. Either the expectation is wrong, or the code is.

    I'm not going to consider any of the remaining output, because this is the first failure.


    I recommend that you look carefully at exactly what's happening in this line of code, and take all of the operator precedence rules into account. I've added spaces to better separate things visually. You may need to refer to a C operator precedence table:
    Code:
       while( ( comp = strncmp(etf1[i].date,etf2[k].date,8) != 0 ) )


    Here's a test program to test whether strncmp() works as documented:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    void show_cmp( char * s1, char * s2 )
    {
        int comp;
    
        comp = strncmp( s1, s2, 8 );
    
        printf( "comp %d for %s : %s\n", comp, s1, s2 );
    }
    
    int main( void )
    {
        show_cmp( "20050615", "20050615" );
        show_cmp( "20050629", "20050630" );
        show_cmp( "20050701", "20050630" );
        return 0;
    }
    
    Here's the output:
    Code:
    comp 0 for 20050615 : 20050615
    comp -1 for 20050629 : 20050630
    comp 1 for 20050701 : 20050630
    
     
  5. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #5
    Thanks again. Don't know what I would do without you.
     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    Gardening?
     
  7. dougphd thread starter macrumors member

    Joined:
    Apr 28, 2016
    #7
    All ready garden. Probably spend more hours pouring over the code until I get it right.
    --- Post Merged, May 29, 2016 ---
    Just took out the print statements to compact the output and ran the code. Of course, it crashed. Don't go away.
     
  8. robvas macrumors 68020

    Joined:
    Mar 29, 2009
    Location:
    USA
    #8
    Farmerdoug! Long time no see. When are you going to learn Python, it's so much better suited for what you are doing.
     

Share This Page