Et pour l'apaiser, Chris, voici une version qui va faire une copie de la première et de la retourner (donc il va travailler sur les littéraux). Vous aurez besoin de free le résultat.
Il est plutôt dangereux de faire cette opération en place. Que faire si la première ligne de main() changé à char *buf = ...; ? Que faire si cela a été utilisé dans plus complexes, le code et les codeurs avait oublié quels sont les arguments qui ont été en écriture tampons et qui ne l'étaient pas? si vous avez besoin de faire une copie, alors vous pouvez toujours faire une copie de la première. Un tel code est encore assez simple. Je ne vois pas comment passer char* ou char[] fait une différence. Aussi, il y a un bug dans strip: la chaîne n'est pas null. il est consered de transmettre quelque chose comme: char *buf = "hello\tworld" qui est illégal parce que vous ne pouvez pas modifier un pointeur vers un littéral. mon strip_copy adresses. Mais +1 pour avoir désobéi à mon attente, la bande-dans-endroit serait inefficace.
Si vous souhaitez remplacer \n ou \t avec quelque chose d'autre, vous pouvez utiliser la fonction strstr(). Elle renvoie un pointeur vers la première place dans une fonction qui a une certaine chaîne de caractères. Par exemple:
//Find the first "\n".char new_char ='t';char* pFirstN = strstr(szMyString,"\n");*pFirstN = new_char;
Vous pouvez exécuter que dans une boucle pour trouver toutes les \n et \t.
Si vous voulez "strip", c'est à dire de les retirer de la chaîne, vous aurez besoin d'utiliser la même méthode que ci-dessus, mais copie le contenu de la chaîne "retour" à chaque fois que vous trouver un \n ou \t, de sorte que "ce i\ns un test" devient: "ceci est un test".
Vous pouvez le faire avec memmove (pas memcpy, depuis la src et dst sont pointant vers le chevauchement de mémoire), comme suit:
char* temp = strstr(str,"\t");//Remove \n.while((temp = strstr(str,"\n"))!= NULL){//Len is the length of the string, from the ampersand \n, including the \n.int len = strlen(str);
memmove(temp, temp +1, len);}
Vous devrez répéter cette boucle de nouveau pour supprimer le \t.
Remarque: ces Deux méthodes de travail en place. Cela pourrait ne pas être en sécurité! (lire Evan Teran les commentaires pour plus de détails.. Aussi, ces méthodes ne sont pas très efficaces, même s'ils n'utilisent une bibliothèque de fonctions pour certains du code au lieu de rouler votre propre.
il semble que ça serait très inefficace pour une longue chaîne. Vous êtes à la recherche de la chaîne (depuis le début), encore et encore. En outre, vous sont en train de faire un strlen chaque fois qu'un char est trouvé). Enfin, vous copiez la fin de la queue de la chaîne à chaque fois qu'un char est trouvé... Vous avez raison, l'efficacité n'était assurément pas un gros souci (c'est en fait le palonnier droit, à partir de code que j'ai eu qui traînent, qui a travaillé seulement avec de petites chaînes de caractères). Le strlen peut être déplacée à l'extérieur de la chaîne, je pense, et la recherche peut commencer à chaque fois à partir du dernier lieu trouvé, au lieu de le début, la négation de la "recherche chaque fois qu'un problème". Cependant, je ne vois pas de moyen de l'éliminer, la nécessité de memmove, s'il le veut, il le fait en place. Toutes les suggestions? Si vous voulez voir un efficace en place la bande alors jetez un oeil à ma réponse :-P. Yep, je l'ai regardé à droite après la publication de mon commentaire, maintenant je me sens stupide 🙂 Au moins, maintenant j'ai quelque chose à changer dans mon projet... +1 pour un travail de réponse et de fournir des mises en garde.
En gros, vous avez deux façons de le faire: vous pouvez créer une copie de la chaîne d'origine, moins tous les '\t' et '\n' caractères, ou vous pouvez enlever la chaîne "en place". Cependant, je parie que la première option sera plus rapide, et je vous promets qu'il sera plus en sécurité.
Nous allons donc faire une fonction:
char*strip(constchar*str,constchar*d);
Nous voulons utiliser strlen() et malloc() pour allouer un nouveau char * tampon de la même taille que notre str tampon. Puis nous passons par str caractère par caractère. Si le personnage est pas contenues dans d, on le copie dans notre nouveau tampon. Nous pouvons utiliser quelque chose comme strchr() pour voir si chaque caractère dans la chaîne d. Une fois que nous aurons terminé, nous avons un nouveau tampon, avec le contenu de nos vieux tampon de moins de caractères dans la chaîne d, donc nous avons juste retour que. Je ne vais pas vous donner un exemple de code, parce que cela pourrait être des devoirs, mais ici, c'est l'exemple de l'utilisation pour vous montrer comment résoudre votre problème:
char*string ="some\n text\t to strip";char*stripped = strip(string,"\t\n");
+1 pour la fourniture de toutes les informations nécessaires pour apprendre comment pour le faire. Les chances sont qu'il est un débutant et que cette information sera utile.
C'est une chaîne c de la fonction qui vous permettra de trouver n'importe quel caractère dans accept et retourner un pointeur à la position de la ou NULL si il n'est pas trouvé.
char search[]="a string with \t and \n";char*first_occ = strpbrk( search,"\t\n");
first_occ le \t, ou le 15 de caractère dans search. Vous pouvez remplacer ensuite l'appel de nouveau pour parcourir en boucle jusqu'à ce que tous ont été remplacés.
J'aime faire de la bibliothèque standard de faire autant de travail que possible, donc je voudrais l'utiliser quelque chose de similaire à Evan solution mais avec strspn() et strcspn().
#include<stdio.h>#include<stdlib.h>#include<string.h>#define SPACE " \t\r\n"staticvoid strip(char*s);staticchar*strip_copy(charconst*s);int main(int ac,char**av){char s[]="this\t is\n a\t test\n test";char*s1 = strip_copy(s);
strip(s);
printf("%s\n%s\n", s, s1);return0;}staticvoid strip(char*s){char*p = s;int n;while(*s){
n = strcspn(s, SPACE);
strncpy(p, s, n);
p += n;
s += n + strspn(s+n, SPACE);}*p =0;}staticchar*strip_copy(charconst*s){char*buf = malloc(1+ strlen(s));if(buf){char*p = buf;charconst*q;int n;for(q = s;*q; q += n + strspn(q+n, SPACE)){
n = strcspn(q, SPACE);
strncpy(p, q, n);
p += n;}*p++='\0';
buf = realloc(buf, p - buf);}return buf;}
Cela fonctionne dans ma rapide et sale tests. Est-il en place:
Et pour l'apaiser, Chris, voici une version qui va faire une copie de la première et de la retourner (donc il va travailler sur les littéraux). Vous aurez besoin de
free
le résultat.main()
changé àchar *buf = ...;
? Que faire si cela a été utilisé dans plus complexes, le code et les codeurs avait oublié quels sont les arguments qui ont été en écriture tampons et qui ne l'étaient pas?si vous avez besoin de faire une copie, alors vous pouvez toujours faire une copie de la première. Un tel code est encore assez simple.
Je ne vois pas comment passer
char*
ouchar[]
fait une différence. Aussi, il y a un bug dansstrip
: la chaîne n'est pas null.il est consered de transmettre quelque chose comme:
char *buf = "hello\tworld"
qui est illégal parce que vous ne pouvez pas modifier un pointeur vers un littéral. monstrip_copy
adresses.Mais +1 pour avoir désobéi à mon attente, la bande-dans-endroit serait inefficace.
OriginalL'auteur Evan Teran
Si vous souhaitez remplacer \n ou \t avec quelque chose d'autre, vous pouvez utiliser la fonction strstr(). Elle renvoie un pointeur vers la première place dans une fonction qui a une certaine chaîne de caractères. Par exemple:
Vous pouvez exécuter que dans une boucle pour trouver toutes les \n et \t.
Si vous voulez "strip", c'est à dire de les retirer de la chaîne, vous aurez besoin d'utiliser la même méthode que ci-dessus, mais copie le contenu de la chaîne "retour" à chaque fois que vous trouver un \n ou \t, de sorte que "ce i\ns un test" devient: "ceci est un test".
Vous pouvez le faire avec memmove (pas memcpy, depuis la src et dst sont pointant vers le chevauchement de mémoire), comme suit:
Vous devrez répéter cette boucle de nouveau pour supprimer le \t.
Remarque: ces Deux méthodes de travail en place. Cela pourrait ne pas être en sécurité! (lire Evan Teran les commentaires pour plus de détails.. Aussi, ces méthodes ne sont pas très efficaces, même s'ils n'utilisent une bibliothèque de fonctions pour certains du code au lieu de rouler votre propre.
Vous avez raison, l'efficacité n'était assurément pas un gros souci (c'est en fait le palonnier droit, à partir de code que j'ai eu qui traînent, qui a travaillé seulement avec de petites chaînes de caractères). Le strlen peut être déplacée à l'extérieur de la chaîne, je pense, et la recherche peut commencer à chaque fois à partir du dernier lieu trouvé, au lieu de le début, la négation de la "recherche chaque fois qu'un problème". Cependant, je ne vois pas de moyen de l'éliminer, la nécessité de memmove, s'il le veut, il le fait en place. Toutes les suggestions?
Si vous voulez voir un efficace en place la bande alors jetez un oeil à ma réponse :-P.
Yep, je l'ai regardé à droite après la publication de mon commentaire, maintenant je me sens stupide 🙂 Au moins, maintenant j'ai quelque chose à changer dans mon projet...
+1 pour un travail de réponse et de fournir des mises en garde.
OriginalL'auteur Edan Maor
En gros, vous avez deux façons de le faire: vous pouvez créer une copie de la chaîne d'origine, moins tous les
'\t'
et'\n'
caractères, ou vous pouvez enlever la chaîne "en place". Cependant, je parie que la première option sera plus rapide, et je vous promets qu'il sera plus en sécurité.Nous allons donc faire une fonction:
Nous voulons utiliser
strlen()
etmalloc()
pour allouer un nouveauchar *
tampon de la même taille que notrestr
tampon. Puis nous passons parstr
caractère par caractère. Si le personnage est pas contenues dansd
, on le copie dans notre nouveau tampon. Nous pouvons utiliser quelque chose commestrchr()
pour voir si chaque caractère dans la chaîned
. Une fois que nous aurons terminé, nous avons un nouveau tampon, avec le contenu de nos vieux tampon de moins de caractères dans la chaîned
, donc nous avons juste retour que. Je ne vais pas vous donner un exemple de code, parce que cela pourrait être des devoirs, mais ici, c'est l'exemple de l'utilisation pour vous montrer comment résoudre votre problème:OriginalL'auteur Chris Lutz
C'est une chaîne c de la fonction qui vous permettra de trouver n'importe quel caractère dans
accept
et retourner un pointeur à la position de la ou NULL si il n'est pas trouvé.Exemple:
first_occ
le \t, ou le 15 de caractère danssearch
. Vous pouvez remplacer ensuite l'appel de nouveau pour parcourir en boucle jusqu'à ce que tous ont été remplacés.OriginalL'auteur user224579
J'aime faire de la bibliothèque standard de faire autant de travail que possible, donc je voudrais l'utiliser quelque chose de similaire à Evan solution mais avec
strspn()
etstrcspn()
.OriginalL'auteur finnw