J'ai travaillé sur un problème de débutant en C pour essayer d'apprendre les bases de C. J'ai remarqué que le problème ci-dessous commencera à l'index de l'endroit où la dernière chaîne prend son envol et finira cette chaîne, mais ce que j'essaye à faire est de joindre les deux chaînes ensemble.
Quelqu'un peut-il m'indiquer la bonne direction? J'essaye de le faire sans réallocation pour apprendre xp.
char *string_dup(char *src)
{
int len = strlen(src);
char *src2 = malloc(len + 1);
int i;
for(i = 0; i < len; i++){
*(src2 + i) = *(src + i);
}
*(src2 + len )='\0';
return src2;
}
void *resize_memory(void *ptr, int old_size, int new_size)
{
char *d = (char*)ptr;
d = malloc(new_size);
}
char *url = string_dup("http://");
char *path = string_dup("website.com/");
int url_length = string_length(url);
int path_length = string_length(path);
int new_length = url_length - 1 + path_length;
char *new_url = resize_memory(url, url_length, new_length);
char *p = new_url + url_length;
while (*path != '\0') {
*p = *path;
p++;
path++;
}
printf("Full path string: %s\n", new_url);
3 Réponses :
Essayez quelque chose comme
char *url = string_dup("http://");
char *path = string_dup("website.com/");
size_t sTotal = strlen(url) + strlen(path) + 1u;
char *pStr = malloc(sTotal);
snprintf(pStr, sTotal, "%s%s", url, path);
free(url);
free(path);
J'ai joué un peu avec votre code puis j'ai trouvé cette solution. Cela vous permet de vous débarrasser de cette fonction string_dup () et de créer une fonction unique qui peut allouer / attribuer une nouvelle chaîne et ajouter une chaîne existante avec plus de données.
int
append_string(char **append_to, char *append_this) {
char *tmp;
// You might want to check that append_this is not
// NULL...
if (*append_to == NULL) {
*append_to = malloc(strlen(append_this) + 1);
strcpy(*append_to, append_this);
}
else {
// Some data already exists on the append_to buffer...
//
// If you want to only use malloc() then make a temporary
// storage area and copy the append_to string there
//
if ((tmp = malloc(strlen(*append_to) + 1)) == NULL)
return -1;
strcpy(tmp, *append_to);
// Free up and re-allocate append_to.
//
free(*append_to);
*append_to = malloc(strlen(tmp) + strlen(append_this) + 1);
if (! append_to) {
fprintf(stderr, "Malloc error...");
exit(EXIT_FAILURE);
}
// Do it with realloc
//
// No temporary buffer required:
//
// *append_to = realloc(
// *append_to,
// (strlen(append_to) + strlen(*append_this) + 1)
// );
// if (! eppend_to) ...realloc error
// Copy the data to the buffer and clean up.
//
sprintf(*append_to, "%s%s", tmp, append_this);
free(tmp);
}
}
/* In your main() or whatever... */
char *url = NULL;
char *path = NULL;
// Since url and path are both NULL the
// append string function will act like
// your string_dup() function...
append_string(&url, "http://");
append_string(&path, "website.com/");
// And not that url is not null it will be
// resized and the path appended.
append_string(&url, path);
fprintf(stdout, "URL: %s\n", url);
// Some housekeeping....
if (url) free(url);
if (path) free(path);
}
J'espère que c'est utile, je sais que c'est un peu différent de ce que vous aviez à l'origine, mais je pensais que je jouerais le jeu!
Problème avec le code OP:
Mauvaise taille
En supposant que string_length () est comme strlen () .
// *s1 is a prior allocated string, or NULL
void ConcatenateString(char **s1, const char *s2) {
char *joined = JoinStrings(*s1, s2);
free(*s1);
*s1 = joined;
}
Redimensionnement inefficace
char *JoinStrings(const char *s1, const char *s2) {
size_t sz = (s1 ? strlen(s1) : 0) + (s2 ? strlen(s2) : 0) + 1;
char *joined = malloc(sz);
if (joined) {
int len = snprintf(joined, sz, "%s%s", s1, s2);
assert(len >= 0 && (unsigned) len < sz); // Failure is very unexpected here.
}
return joined;
}
Je m'attendrais à quelque chose comme
// s1, s2 may be NULL. A NULL is treated as if ""
char *JoinStrings(const char *s1, const char *s2) {
size_t len1 = s1 ? strlen(s1) : 0;
size_t len2 = s2 ? strlen(s2) : 0;
char *joined = malloc(len1 + len2 + 1);
if (joined) {
memcpy(joined, s1, len1);
memcpy(joined + len1, s2, len2);
joined[len1 + len2] = '\0';
}
return joined;
}
Façons de joindre des chaînes avec realloc () avec allocation.
Exemple de code:
// return failure status
bool resize_memory(void **ptr_addr, size_t old_size, size_t new_size) {
void *new_ptr = NULL;
if (new_size > 0) {
new_ptr = malloc(new_size);
if (new_ptr) { // Out of memory, leave *ptr_addr alone
return true;
}
size_t min_size = old_size < new_size ? old_size : new_size;
memcpy(new_ptr, *ptr_addr, min_size);
}
free(*ptr_addr);
*ptr_addr = new_ptr;
return false;
}
Ou via snprintf()
void *resize_memory(void *ptr, int old_size, int new_size) {
char *d = (char*)ptr; // assign `d`
d = malloc(new_size); // Why re-assigned `d`???
// No use of old_size, new_size
// No copying of existing data
// No freeing of old allocation
}
Pour concaténer comme (* s1) + = s2
// int new_length = url_length - 1 + path_length; int new_length = url_length + 1 + path_length;
L'exercice est-il ici pour réimplémenter
strdup? Je veux juste comprendre l'objectif.Remarque: il est conventionnel d'utiliser
size_tau lieu deintpour les longueurs. Il s'agit d'un entier non signé car les tailles manifestement négatives n'ont aucun sens.Il semble également que vous deviez activer beaucoup plus d'avertissements, même
-Wall, car votre fonctionresize_memoryne renvoie rien, mais promet de renvoyervoid * < / code>. Ce code ne peut pas fonctionner tant que vous neretournez pas dN'oubliez pas de libérer cette mémoire!
resize_memorydevrait probablement également copier l'ancien tampon dans le nouveau.Demandez-vous ce que vous voulez exactement. Je pense que vous avez besoin d'un
char * join (const char * s, const char * t)qui allouestrlen (s) + strlen (t) + 1puis copies(moins null) ettdans le tampon, peut-être en utilisantmemcpy.oh je sais que c'est un problème de débutant pour C. Je suis un débutant.
@ chargerfan619 Cherchez-vous à écrire une nouvelle fonction ou à modifier l'une des fonctions existantes que vous avez publiées ici?
J'essaye d'obtenir printf ("Chaîne de chemin complet:% s \ n", nouvelle_url); égal à "http: // website.com/" en modifiant la fonction resize_memory
OK, strlen (const char *) est une fonction de bibliothèque, mais qu'est-ce que string_length (char *)?
La fonction resize_memory ne renvoie rien. Soit vous souhaiterez changer la valeur de retour de void en char *, soit vous souhaiterez utiliser un double pointeur.