2010-03-03 5 views
4

Je sais, que si je veux comparer deux structs que je dois l'écrire pour moi-même, parce qu'il n'y a aucune fonction pour cela, mais je ne peux pas comprendre comment devrais-je faire cela. J'ai trois structures: primaire, secondarystruct, et différence (ceci devrait contenir les différents articles). Tous les trois ont les membres suivants: char * filename, char * size, int size. Tout ce dont j'ai besoin, ce sont les éléments qui ne sont pas dans la chaîne secondaire, ou s'ils en ont besoin, je n'en ai besoin que si leur taille est plus grande que la taille du secondaire. J'espère que vous comprenez ce que je veux. Mon anglais n'est pas le meilleur, désolé pour cela.Comment comparer deux structs dans c?

Voici ce que j'ai essayé:

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

S'il vous plaît me dire ce que je fais mal!

Merci, Kampi

Mise à jour:

Désolé, il semble, je vous ai donné des informations ne suffit pas. Donc: les deux structures contiennent une liste de fichiers, provenant de différents lecteurs, comme "C: \" et "D: \". C'est la raison pour laquelle je ne peux pas utiliser simplement strcmp, car la première lettre sera toujours différente. C'est pourquoi je dois les "couper" et ensuite comparer. Ce programme devrait fonctionner comme ceci: Il récupère la liste de fichiers de c: \ et récupère ensuite la liste de fichiers de d: \, puis les compare. Si le fichier qui est sur c: \ n'existe pas sur d: \ alors il devrait être copié là, si sur d: \ il y a un fichier qui n'existe pas sur c: \ alors il devrait être ignoré (je ne sais pas Je ne veux rien faire avec ça. Si un fichier que l'on trouve dans c: \ et d: \, alors je ne le copierai que si le fichier de c: \ a une taille plus grande qu'un fichier qui est sur d: \

J'espère que vous comprenez maintenant ce que je veux.

+0

Hors sujet, mais encore, vous faites i ++ dans chaque branche, pourquoi ne pas mettre cela dans la boucle for où il appartient? :) – falstro

+0

@roe: Vous avez remarqué que l'incrément mais manqué strlen utilisé dans une condition de boucle? : P @kampi: Les boucles dont je parle (et l'instruction suivante de 'buf [k] = '\ 0'') sont mieux remplacées par des appels strcpy. –

+0

@kampi: Pouvez-vous reformuler la partie - _Ill faut-il des éléments qui ne sont pas dans le secondarystruct_? Voulez-vous dire que vous avez besoin de la différence d'un ensemble de ces structures? De même, quand deux éléments sont-ils égaux si leurs noms de fichiers sont identiques? Notez que vous ne pouvez probablement pas avoir deux membres appelés taille dans une seule structure. – dirkgently

Répondre

2

La cause la plus probable de votre « gel » est l'appel strlen(), qui est probablement causée par un problème de mémoire (ie. Que son argument n'est pas un pointeur sur chaîne terminée par zéro). Il peut y avoir plusieurs causes de cette:

  • vous avez peut-être réécrites une partie de votre mémoire par un dépassement de mémoire tampon (de tmp ou buf).
  • Je suppose que vous utilisez x comme un indicateur que vous êtes allé à la fin, mais vous utilisez secondarystruct[j] après cela.De plus, si secondarypcs a la même signification que primarypcs, c'est-à-dire le nombre d'éléments d'un tableau, vous utilisez secondarystruct[secondarypcs], mais c'est hors limite.

Quelques autres conseils:

  • si le premier fichier secondarypcs est manquant dans primarypcs, votre code mettra tout à diff, peu importe quoi.
  • comparant les chaînes quelle que soit la première lettre peut être fait comme ceci:

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

Je suggère code comme ceci:

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

Merci beaucoup! C'est exactement ce dont j'avais besoin! – kampi

0

Vous devez comparer les structures par champ. Utilisez strcmp pour les chaînes char * et les opérateurs de comparaison pour les entiers. Normalement vous feriez une fonction séparée pour comparer et la fonction retournerait 0 si les structures sont les mêmes, une valeur négative si la première est "plus petite" et une valeur positive si la première est plus grande.

+2

memcmp sur les structures est quelque peu risqué car il peut y avoir un remplissage à l'intérieur et ensuite vous finirez par comparer cela aussi bien. – Tronic

1

Si vous avez les mêmes variables de structure. Accédez à chaque membre des variables struct, puis effectuez une comparaison appropriée. vous devez comparer les valeurs en fonction de leurs types de données.

0

Ceci est trop de code si vous voulez simplement accomplir ce que vous dites. Il suffit d'utiliser strcmp() pour comparer les noms de fichiers et les tailles, et ">" pour la taille. Puis, en se basant sur le résultat de la comparaison, vous pouvez copier les membres appropriés dans la structure de différence en utilisant strdup() ou simple "=" pour les entiers.

 
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... 
} 
1

vous pouvez comparer les structures en utilisant la fonction memcmp(). Si vous spécifiez les structures et sa longueur dans le memcmp, il comparera et retournera les résultats en entier comme pour strcmp.

Mais c'est mieux que la fonction strcmp(). Il traite directement de la mémoire. il peut donc donner des résultats précis.