J'ai une fonction qui rend récursivement certains calculs sur un ensemble de nombres. Je tiens également à imprimer le calcul dans chaque appel de récursivité en faisant passer la chaîne du calcul précédent et en concaténant avec l'opération en cours. Une sortie d'échantillon peut ressembler à ceci:
/********************************************************************** * dynamically allocate and append new string to old string and return a pointer to it **********************************************************************/ char * strapp(char * old, char * new) { // find the size of the string to allocate int len = sizeof(char) * (strlen(old) + strlen(new)); // allocate a pointer to the new string char * out = (char*)malloc(len); // concat both strings and return sprintf(out, "%s%s", old, new); return out; } /********************************************************************** * returns a pretty math representation of the calculation op **********************************************************************/ char * mathop(char * old, char operand, int num) { char * output, *newout; char fstr[50]; // random guess.. couldn't think of a better way. sprintf(fstr, " %c %d", operand, num); output = strapp(old, fstr); newout = (char*)malloc( 2*sizeof(char)+sizeof(output) ); sprintf(newout, "(%s)", output); free(output); return newout; } void test_mathop() { int i, total = 10; char * first = "3"; printf("in test_mathop\n"); while (i < total) { first = mathop(first, "+", i); printf("%s\n", first); ++i; } }
4 Réponses :
Un problème immédiat que je peux voir est la suivante:
int len = sizeof(char) * (strlen(old) + strlen(new));
Le NULL CHART est couvert par TIMILOF (CHAR)
@kenny non, ce n'est pas le cas. Testez-le pour vous-même.
@kenny: permet de dire que le vieux est "1" et nouveau est "2". Les deux ont une chaine de 1. Vous voulez maintenant les concaténer dans une seule chaîne. Il devrait accueillir '1', '2' et le '\ 0', pour marquer la fin de la chaîne. Nous avons donc besoin d'un moyen supplémentaire de la somme des longueurs de chaîne.
Vous devez allouer un octet supplémentaire pour la terminaison 0.
et vous devez utiliser strlen code> au lieu de
Tailleof code> ici: p>
newout = (char*)malloc( 2*sizeof(char)+sizeof(output) );
Je pensais que Strstr était de trouver une sous-chaîne dans une autre chaîne
Non seulement il doit allouer de l'espace de la traînée \ 0, mais il doit aussi mettre \ 0 là-bas.
@shacharptooth BON POINT En effet, vaut la peine de mentionner explicitement. Bien que strcat code> le gérerait automatiquement.
Essayez ceci, pour commencer: Ceci est juste votre code, avec un certain nombre de correctifs: p> Pour la performance, vous pouvez utiliser le fait que vous appelez
const code>. li>
Taille_t code>. Li>
Tailleof (Char) Code>. Li>
MALLOC () CODE>. LI>
STR code>, c'est un espace réservé. Souligné par le commentateur, merci! Li>
ul>
strallen () code> sur les deux entrées et évitez d'utiliser
sprintf () code>:
char * append_strings(const char * old, const char * new)
{
// find the size of the string to allocate
const size_t old_len = strlen(old), new_len = strlen(new);
const size_t out_len = old_len + new_len + 1;
// allocate a pointer to the new string
char *out = malloc(out_len);
// concat both strings and return
memcpy(out, old, old_len);
memcpy(out + old_len, new, new_len + 1);
return out;
}
C'est techniquement une mauvaise idée de donner un nom de fonctions commençant par "STR".
@sgm Vous avez raison, mais IMO, cela devrait être un commentaire sur la question initiale.
@SGM: Vous avez absolument raison, je vais modifier pour inclure cela comme une amélioration.
Merci pour toutes les réponses, elles ont été très utiles - en particulier les suggestions Strcat et découvrons que je devais allouer de l'espace pour le caractère «\ 0». J'ai fini par utiliser Realloc pour "étirer" la chaîne et appendez des caractères principaux et de fin. J'ai également éliminé la fonction Strapp (append_strings) et j'ai tout compris à travailler à l'intérieur de Mathop. Voici comment:
/********************************************************************** * returns a pretty math representation of the calculation op **********************************************************************/ char * mathop(char * previous, char operand, float num) { char *output, *temp, calculation[50]; size_t newlen; // copy the previous data into the temp string temp = (char*)malloc( strlen(previous) + 1 ); output = (char*)malloc(2); strcpy(temp, previous); strcpy(output, "(\0"); // create the string portion to append to the output sprintf(calculation, " %c %.1f)\0", operand, num); // reallocate the output to append the additional string newlen = strlen(temp) + strlen(calculation) + 1; temp = realloc(temp, newlen); // append the new data to output strcat(temp, calculation); output = realloc(output, strlen(temp) + 2); strcat(output, temp); printf("%s\n", output); free(temp); return output; }
La taille de (sortie) vous donnera la taille d'un pointeur. Très différent de SHLEN.
Vous n'avez pas initialisé i b> !!
Vous devriez probablement supprimer la taille de (char), c'est juste une grande façon d'écrire 1 qui clutters les choses et le pire des cas) ajoute de la confusion.
@Agnel Pourquoi ne les ajoutes-tu pas comme une réponse? Je dirais que vous méritez certains + pour vos observations :-)
@ Péter Török - Je ne me suis pas senti trop confiant à propos de ces réponses. Mais vous avez un point là-bas ...
@ SA125 - Où avez-vous reçu le nom "SA125"? Juste curieux. Une fois, j'ai su 125 sa 125 il y a longtemps ...