2010-11-17 5 views
3

D'après mon post précédent, j'ai trouvé le code suivant. Je suis sûr qu'il y a une meilleure façon de le faire. Je me demande, qu'est-ce que ce serait?c - manipulation de chaîne pour le membre struct

Il divise la chaîne si le nombre maximal de caractères est OR si @ est trouvé. Toute idée serait appréciée!

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

struct my_struct { 
    char *str; 
}; 

int main() { 
    struct my_struct *struc; 

    int max = 5; 
    char *tmp = "Hello [email protected] Bar In [email protected] Foo dot [email protected]@there"; 

    struc = malloc (20 * sizeof (struct my_struct)); 

    int strIdx = 0, offSet = 0; 
    char *p = tmp; 
    char *tmpChar = malloc (strlen (tmp) + 1), *save; 
    save = tmpChar; 

    while (*p != '\0') { 
    if (offSet < max) {    
     offSet++; 
     if (*p == '@') { 
     if (offSet != 1) { 
      *tmpChar = '\0'; 
      struc[strIdx++].str = strndup (save, max); 
      save = tmpChar; 
     } 
     offSet = 0; 
     } else 
     *tmpChar++ = *p; 
    } else {     // max 
     offSet = 0; 
     *tmpChar = '\0'; 
     struc[strIdx++].str = strndup (save, max); 
     save = tmpChar; 
     continue; 
    } 
    p++; 
    } 
    struc[strIdx++].str = strndup (save, max); // last 'save' 

    for (strIdx = 0; strIdx < 11; strIdx++) 
    printf ("%s\n", struc[strIdx].str); 

    for (strIdx = 0; strIdx < 11; strIdx++) 
    free (struc[strIdx].str); 
    free (struc); 
    return 0; 
} 

Sortie à 5 caractères max:

Hello 
Worl 
d 
Foo B 
ar In 
here 
Bar F 
oo do 
t com 
here 
there 
+0

Un commentaire (comme un commentaire): les noms comme 'i',' j', 'p',' c', 'ss' et' s' ne facilitent pas la lecture du code. Si 'j' est vraiment' offset', appelez ça. Il semble que 'i' est un index dans votre tableau de structures. 'string_idx',' strIdx', ou même 'idx' seraient plus significatifs. – nmichaels

+0

@Nathon: Merci pour l'observation, je l'ai rendu un peu plus lisible :) – Mike

Répondre

1

D'accord, je vais prendre une fissure à elle. Tout d'abord, laissez-moi vous dire que mes changements de formatage étaient pour moi. Si vous n'aimez pas la solitude, c'est bien.

#define _GNU_SOURCE 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAX 5 

struct string_bin 
{ 
    char *str; 
}; 


int main() 
{ 
    struct string_bin *strings; 

    char *tmp = "Hello [email protected] Bar In [email protected] Foo dot [email protected]@there"; 

    char *p = tmp; 
    strings = malloc (20 * sizeof (struct string_bin)); 
    memset(strings, 0, 20 * sizeof (struct string_bin)); 

    int strIdx = 0, offset = 0; 
    char *cursor, *save; 

    strings[strIdx].str = malloc(MAX+1); 
    save = strings[strIdx].str; 
    while (*p != '\0') 
    { 
     if (offset < MAX && *p != '@') 
     { 
      *(save++) = *(p++); 
      offset++; 
      continue; 
     } 
     else if (*p == '@') 
      *p++; 
     offset = 0; 
     *save = '\0'; 
     strings[++strIdx].str = malloc(MAX+1); 
     save = strings[strIdx].str; 
    } 
    *save = '\0'; 

    for (strIdx = 0; strings[strIdx].str != NULL; strIdx++) 
    { 
     printf ("%s\n", strings[strIdx].str); 
     free (strings[strIdx].str); 
    } 

    free (strings); 

    return 0; 
} 

Le grand changement est que je me suis débarrassé de vos appels strdup. Au lieu de cela, j'ai bourré la chaîne directement dans son tampon de destination. J'ai également fait plus d'appels à malloc pour les tampons individuels de chaîne. Cela vous permet de ne pas connaître la longueur de la chaîne d'entrée à l'avance au prix de quelques allocations supplémentaires.

+0

J'aime votre approche de se débarrasser des appels strdup. Merci! – Mike