Как сравнить две структуры в c? - PullRequest
4 голосов
/ 03 марта 2010

Я знаю, что если я хочу сравнить две структуры, я должен написать это для себя, потому что для этого нет никакой функции, но я не могу понять, как мне это сделать. У меня есть три структуры: первичная, вторичная и разностная (в ней должны быть разные элементы). Все три имеют следующие члены: char * имя файла, char * размер, int размер.

Все, что мне нужно, это те предметы, которые не находятся во вторичной структуре, или если они есть, тогда они нужны мне, только если их размер больше размера вторичной структуры. Надеюсь, ты понимаешь, чего я хочу. Мой английский не самый лучший, извините за это.

Вот что я попробовал:

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++;
    }
}

Пожалуйста, скажите мне, что я делаю неправильно!

Спасибо, Кампи

Обновление:

Извините, кажется, я дал вам недостаточно информации. Итак: обе структуры содержат список файлов с разных дисков, таких как «C: \» и «D: \». Это причина, почему я не могу использовать просто простой strcmp, потому что первая буква всегда будет отличаться. Вот почему я должен «отрезать их», а затем сравнить. Эта программа должна работать следующим образом: она извлекает список файлов из c: \, а затем извлекает список файлов из d: \ и затем сравнивает их. Если для файла, находящегося в каталоге c: \, не существует в d: \, его следует скопировать туда, если в каталоге d: \ есть файл, которого не существует в c: \, то его следует игнорировать (я не не хочу ничего с этим поделать). Если файл, который также находится в c: \ и d: \, я не хочу копировать его только тогда, если файл из c: \ имеет больший размер, чем файл, находящийся в d: \

Надеюсь, теперь ты понимаешь, чего я хочу.

Ответы [ 5 ]

2 голосов
/ 03 марта 2010

Наиболее вероятной причиной вашего "зависания" является вызов strlen(), который, вероятно, вызван некоторой проблемой с памятью (то есть, что его аргумент не является указателем на строку, оканчивающуюся на ноль). Причин может быть несколько:

  • Вы могли перезаписать часть вашей памяти переполнением буфера (tmp или buf).
  • Полагаю, вы используете x в качестве индикатора, до которого вы дошли, но после этого вы используете secondarystruct[j]. Более того, если secondarypcs имеет то же значение, что и primarypcs, то есть количество элементов массива, вы используете secondarystruct[secondarypcs], но это выходит за пределы.

Некоторые другие советы:

  • если первый файл в secondarypcs отсутствует в primarypcs, ваш код будет помещать все в diff, несмотря ни на что.
  • сравнение строк независимо от первой буквы можно сделать так:

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

Я бы предложил такой код:

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
}
1 голос
/ 06 марта 2010

Вы можете сравнить структуры, используя функцию memcmp (). Если вы укажете структуры и его длину в memcmp, они будут сравнивать и возвращать результаты в целых числах, как strcmp.

Но это лучше, чем функция strcmp (). Это напрямую связано с памятью. так что это может дать результаты точно.

1 голос
/ 03 марта 2010

Если у вас одинаковые структурные переменные.Получите доступ к каждому члену переменных структуры, затем выполните соответствующее сравнение.вам нужно сравнить значения на основе их типов данных.

0 голосов
/ 03 марта 2010

Это слишком много кода, если вы просто хотите выполнить то, что вы говорите.

Просто используйте strcmp () для сравнения имен файлов и размеров, а ">" для размера. Затем, основываясь на результате сравнения, вы можете скопировать соответствующие элементы в структуру различий, используя strdup () или простое "=" для целых чисел.

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...
}
0 голосов
/ 03 марта 2010

Вы должны сравнивать структуры поле за полем. Используйте strcmp для строк char * и операторы сравнения для целых чисел. Обычно вы делаете отдельную функцию для сравнения, и функция возвращает 0, если структуры одинаковы, отрицательное значение, если первый «меньше», и положительное значение, если первый больше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...