tags:

views:

264

answers:

5

Hi!

I know, that if i want to compare two structs than i have to write it for myself, because there isn't any function for this, but i can't figure out how should i do that. I have three structs : primary, secondarystruct, and difference(this should contain the different items). All three has the following members : char * filename, char * size, int size.

All i need are those items which aren't in the secondarystruct , or if they are then i need them only if their size is bigger then the secondarystruct's size. Hope you understand what i want. My english isn't the best, sorry for this.

Here is what i tried:

j = 0;
x = 0;
for ( i = 0; i < primarypcs; )
{
    memset( tmp, 0, sizeof( tmp ) );
    l = 1;
    for ( k = 0; k < strlen( primary[i].filename );k++ )
    {
        tmp[k] = primary[i].filename[l];
        l++;
    }
    tmp[k]='\0';

    memset( buf, 0, sizeof( buf ) );
    l = 1;
    for ( k = 0; k < strlen( secondarystruct[j].filename ); k++ ) //<-- here is where my program freezes
    {
        buf[k] = secondarystruct[j].filename[l];
        l++;
    }
    buf[k]='\0';

    if ( ( stricmp( tmp, buf ) == 0 ) && ( x == 0 ) )
    {
        if ( primary[i].intsize > secondarystruct[j].intsize )
        {
            difference[diff].filename = strdup( primary[i].filename );
            difference[diff].size = strdup( primary[i].size );
            difference[diff].intsize = -1;
            diff++;
            i++;
            if ( j == secondarypcs ) x = 1;
            else j++;
        }
        else if ( x == 0 )
        {
            i++;
            if ( j == secondarypcs ) x = 1;
            else j++;
        }
    }
    else
    {
        difference[diff].filename = strdup( primary[i].filename );
        difference[diff].size = strdup( primary[i].size );
        difference[diff].intsize = -1;
        diff++;
        i++;
    }
}

Please tell me what i'm doing wrong!

Thanks, kampi

Update:

Sorry, it seems, i gave you not enough information. So: both structures are containing file list, from different drives, like "C:\" and "D:\". This is the reason why i can't use just simple strcmp, because the first letter will always differ. That's why i have to "cut them off" and then compare. This program should work like this: It retrieves the file list from c:\ and then retrieves the filelist from d:\ and then compares them. If on file which is on c:\ doesn't exists on d:\ then it should be copied there, if on d:\ there is a file which doesn't exists on c:\ then it should be ignored(i don't wan't to do with it anything). If a file which is found in c:\ and d:\ as well, then i wan't to copy it only then if the file from c:\ has a bigger size than a file which is on d:\

Hope you understand now what i want.

A: 

You must compare structs field by field. Use strcmp for char* strings and comparison operators for integers. Normally you would make a separate function for comparing and the function would return 0 if the structs are the same, a negative value if the first one is "smaller" and a positive value if the first one is bigger.

Tronic
Using memcmp on the structs is somewhat risky as there may be padding within and then you'll end up comparing that as well.
Tronic
+1  A: 

If you have same structure variables. Access each member of the struct variables , Then do appropriate comparison . you need to compare the values based on their data types.

pavun_cool
A: 

This is too much code if you just want to accomplish what you say.

Just use strcmp() to compare filenames and sizes, and ">" for size. Then basing on the result of comparison, you may copy appriopriate members to difference structure using strdup() or simple "=" for integers.

if (!strcmp(first.filename, second.filename) {
    ...what to do, when they are different...
}
if (!strcmp(first.size, second.size) {
    ...what to do, when they are different...
}
if (first.intsize != second.intsize) {
    ..etc...
}
pajton
+2  A: 

The most probable cause of your "freeze" is the strlen() call, which is likely caused by some memory problem (ie. that its argument isn't a pointer to string terminated by zero). There may be multiple causes of this:

  • you may have overwritten some of your memory by a buffer overflow (of tmp or buf).
  • I assume you're using x as an indicator you've gone to the end, but you use secondarystruct[j] after that. Moreover, if secondarypcs has the same meaning as primarypcs, that is, the count of elements of an array, you're using secondarystruct[secondarypcs], but that's out-of-bounds.

Some other tips:

  • if the first file in secondarypcs is missing in primarypcs, your code will put everything to diff, no matter what.
  • comparing the strings regardless of the first letter can be done like this:

    (*str1 && *str2 ? strcmp(str1+1, str2+1) : -1)

I'd suggest code like this:

void add_to_difference(struct diff_file* f);

...

// assuming primarystruct and secondarystruct are arrays of diff_file sorted by filename
j=0;
for(i=0; i<primarypcs; i++) {
  // find a passibly matching secondary file
  while(j<secondarypcs && strcmp(primarystruct[i].filename+1, secondarystruct[j].filename+1)<0)
    j++;
  // not found... add all overflow items to diff
  if(j>=secondarypcs) {
    for(; i<primarypcs; i++)
      add_to_diff(primarystruct+i);
    break;
  }
  // do the comparison
  if(strcmp(primarystruct[i].filename+1, secondarystruct[j].filename+1)>0 || 
    primarystruct[i].intsize>secondarystruct[j].intsize)
    add_to_diff(primarystruct+i);
  // that's it
}
jpalecek
Thank you very much! This is exactly what i needed!
kampi
+1  A: 

you can compare the structures using memcmp() function. If you specify the structures and its length in the memcmp it will compare and returns the results in integer as like strcmp.

But It is better than the strcmp() function. It directly deals with memory. so it can give results accurately.

sganesh