2010-11-16 4 views
2

Comment affecter des valeurs au membre struct caractère par caractère. Je voudrais faire quelque chose commestructure caractère par caractère dans c

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

struct s 
{ 
    char *z; 
}; 

int main() 
{ 

    struct s *ss; 
    ss = malloc(2 * sizeof *ss); 

    char *str = "Hello World-Bye Foo Bar"; 
    char *a = str; 
    int i = 0; 
    while (*a != '\0') { 
     if (*a == '-') 
      i++; 
     else ss[i].z = *a; // can I do this? 
     a++; 
    } 
    for(i = 0; i<2; i++) 
     printf("%s\n",ss[i].z); 
} 

Je peux obtenir quelque chose comme:

ss[0].z = "Hello World" 
ss[1].z = "-Bye Foo Bar" 

Edit: oublié de mentionner, le nombre de "-" dans str peut varier.

+0

@pmg: #s retiré :) – Mike

+1

J'aime mieux ça. bienvenue à SO :-) – pmg

+0

Le nombre de '-' dans la chaîne de changement ne change pas grand chose. Essentiellement, vous voulez répéter le processus que j'ai décrit de manière à ce que vous terminiez la chaîne précédente où vous avez trouvé le prochain '-' et appelez à nouveau strdup, mais en utilisant la chaîne en cours. – Flexo

Répondre

3

Si const char *str n'a pas été const, vous pouvez insérer un '\0' pour diviser la chaîne en deux. Vous devez également déplacer les autres caractères vers le «droit».

La solution propre est d'utiliser quelque chose comme strdup pour faire deux copies de la chaîne, dont vous, tôt le mettez fin à un autre dont début de la copie par mi-chemin:

par exemple

ss[0].z = strdup(str); 
ss[1].z = strdup(strchr(str, '-')); 
const size_t fist_part = strlen(str)-strlen(ss[1].z); 
ss[0].z[first_part] = 0; 

Mise à jour: Vous pouvez l'utiliser, même avec plus d'un « - »

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

struct s 
{ 
    char *z; 
}; 

int main() 
{ 
    struct s *ss; 
    ss = malloc(20 * sizeof(struct s)); 

    const char *str = "Hello World-Bye Foo Bar-more-and-more-things"; 
    int i = 1; 
    char *found = NULL; 
    ss[0].z = strdup(str); 
    while ((found = strchr(ss[i-1].z, '-'))) { 
    // TODO: check found+1 is valid! 
    ss[i].z = strdup(found+1); 
    *found = 0; 
    ++i; 
    } 
    for(i = 0; i<6; i++) 
    printf("%s\n",ss[i].z); 

    return EXIT_SUCCESS; 
} 

En pratique, vous voulez être plus prudent pour éviter les bugs avec des entrées inattendues de sorte que vous devez être que vous gérez:

  • Il n'y a pas '-' omble chevalier
  • Il n'y a pas '\ 0' à
  • échec d'allocation

N'oubliez pas free() aussi!

+1

+1 pour le terminateur NUL :-) – pmg

+0

@awoodland, merci pour votre commentaire, je préfère ne pas utiliser strdup() dans ce cas, car je ne suis pas sûr de combien "-" str contiendra. – Mike

+0

Si vous ne dupliquez pas les chaînes ou n'allouez pas de mémoire supplémentaire, vous ne pouvez pas le faire. Le problème est de diviser la chaîne dont vous avez besoin pour insérer un caractère '\ 0' supplémentaire à chaque fois que vous voulez le décomposer, mais pour ce faire, vous devez: a) avoir un "espace" disponible dans la chaîne et b) être capable de légalement modifier la chaîne, qui n'est pas possible sans au moins un appel à malloc, et beaucoup plus propre avec un appel par fragment de la chaîne que vous souhaitez conserver. – Flexo

0
else ss[i].z = *a; // can I do this? 

Oui, vous pouvez le faire. MAIS vous devez d'abord allouer de l'espace pour chaque z ... et n'oubliez pas de mettre fin aux chaînes!

ss = malloc(2 * sizeof *ss); 
ss[0].z = malloc(1000); /* don't do it */ 
ss[1].z = malloc(1000); /* like this! */ 
0

Vous aurez besoin d'allouer de nouveaux blocs de mémoire pour contenir les chaînes fractionnées (au moins la première).

char *s1, *s2, *a, *b; 

const char *str = "Hello World-Bye Foo Bar"; 

s1 = malloc(strlen(str)+1); 
s2 = malloc(strlen(str)+1); 

a = str; 

int i = 0; 
ss[0].z = s1; 
b = ss[0].z; 
while (*a != '\0') { 
    if (*a == '-') { 
     i++; 
     ss[i].z = s2; 
     *b = ss[i].z; 
     *b++ = *a; 
    } else { 
    // s[i].z = *a // can I do this? (yes, but it you might not be happy with the result :-) 
     *b++ = *a; // try this instead... 
    } 
    a++; 
} 
Questions connexes