Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

dougphd

macrumors member
Original poster
Apr 28, 2016
70
0
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
 
Last edited by a moderator:
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.
 
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
 
Last edited by a moderator:
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
 
Last edited:
All ready garden. Probably spend more hours pouring over the code until I get it right.
[doublepost=1464566484][/doublepost]Just took out the print statements to compact the output and ran the code. Of course, it crashed. Don't go away.
 
Farmerdoug! Long time no see. When are you going to learn Python, it's so much better suited for what you are doing.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.