I ont une carbonisation buf [x], s int et void * data.C - chaîne lu à partir du tampon d'une certaine taille
Je veux écrire une chaîne de taille s en données de buf.
Comment faire cela?
Merci d'avance.
I ont une carbonisation buf [x], s int et void * data.C - chaîne lu à partir du tampon d'une certaine taille
Je veux écrire une chaîne de taille s en données de buf.
Comment faire cela?
Merci d'avance.
En supposant que
data
;D'abord, vous devez allouer de la mémoire dans data
. Ne pas oublier la pièce pour le 0
octet à la fin de la chaîne.
data = malloc(s+1);
if (data == NULL) {
... /*out-of-memory handler*/
}
En supposant malloc
réussit, vous pouvez maintenant copier les octets.
EDIT:
La meilleure fonction pour le travail, comme l'a souligné café, est strncat
. (Il est entièrement portable, faisant partie de C89.) Il ajoute à la chaîne de destination, donc prendre des dispositions pour la destination à une chaîne vide au préalable:
*(char*)data = 0;
strncat(data, buf, s);
D'autres possibilités de qualité inférieure, gardé ici pour servir d'exemples de fonctions connexes:
Si vous ont strlcpy
(ce qui est la norme C mais est commun sur les systèmes Unix modernes, il existe des implémentations de domaine public flottant autour):
strlcpy(data, buf, s+1);
Si vous savez qu'il ya au moins s
caractères dans la chaîne source, vous pouvez utiliser memcpy
:
memcpy(data, buf, s);
((char *) données) [s + 1] = 0;
Sinon, vous pouvez calculer la longueur de la chaîne source première:
size_t bytes_to_copy = strlen(buf);
if (bytes_to_copy > s) bytes_to_copy = s;
memcpy(data, buf, bytes_to_copy);
((char*)data)[s+1] = 0;
Ou vous pouvez utiliser strncpy
, mais il est inefficace si la longueur réelle de la chaîne source est beaucoup plus petite que s
:
strncpy(data, buf, s);
((char*)data)[s+1] = 0;
Vos implémentations de 'memcpy()' ont des bogues - elles placent toutes deux incorrectement le terminateur nul, et elles essaient de déréférencer un 'void *', ce que vous ne pouvez pas faire. Le premier devrait utiliser '((char *) data) [s] = 0', et le second devrait utiliser' ((char *) data) [bytes_to_copy] = 0; '. Pour le dernier, au lieu de 'strncpy()' vous pouvez utiliser 'strncat()': '((char *) data) [0] = 0; strncat (data, buf, s); ' – caf
@caf: vous avez raison sur les deux points. Malheureusement ma réponse a été acceptée, donc je l'ai édité plutôt que de la supprimer parce que je ne veux pas laisser une mauvaise réponse trop visible. Mais si vous écrivez une réponse strncat, je vais l'augmenter. – Gilles
memcpy(data, buf, s);
Cela suppose que vous avez suffisamment d'espace dans les données (et dans buf). En fonction de ce que vous faites (vous ne dites pas, mais vous dites que vous copiez des chaînes), vous pouvez ajouter une valeur nulle à la fin de votre chaîne nouvellement copiée si vous n'avez pas copié une valeur nulle déjà en cours, et vous allez utiliser des données dans une fonction qui attend des chaînes.
data = malloc(s);
strcpy((char*)data,buf);
free(data);
Si data
est pas affectée:
char buf[] = "mybuffer";
void *data = malloc(strlen(buf)+1);
strcpy((char*)data,buf);
En fait, si les données sont vraiment à définir, vous pouvez également faire
char buf[] = "mybuffer";
void *data= (void*)strdup(buf);
Vous devriez 'malloc (strlen (buf) +1)' – sje397
Les littéraux de chaîne ne sont-ils pas déjà terminés par un caractère nul? – Jack
Oui, et ici 'buf' est null-terminé même si [ce n'est pas un littéral de chaîne] (http://c-faq.com/aryptr/aryptr2.html). Mais 'strlen (buf)' n'inclut pas l'octet de terminaison dans son compte. – Gilles
int n = MIN((x - 1), s);
char *bp = buf;
char *dp = (char *)data;
while (n--) {
*bp++ = *dp++;
}
*dp = '\0';
Est-ce que 'buf' est une chaîne délimitée par des zéros ou sa taille est-elle définie par' s'? Essayez-vous de copier seulement une partie de la chaîne? Qu'est-ce que 'x'? La chaîne copiée dans 'data' doit-elle être délimitée par des zéros? Qu'avez-vous essayé jusqu'à présent? – zvone
note que caf a souligné plusieurs erreurs dans ma réponse. J'ai édité ma réponse pour tenir compte de ses commentaires. – Gilles