Suppression du caractère de fin de ligne de l'entrée fgets ()

236

J'essaie d'obtenir des données de l'utilisateur et de les envoyer à une autre fonction dans gcc. Le code est quelque chose comme ça.

printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}

Cependant, je trouve qu'il a un \ncaractère de nouvelle ligne à la fin. Donc, si j'entre, Johnil finit par envoyer John\n. Comment puis-je supprimer cela \net envoyer une chaîne appropriée.

sfactor
la source
21
if (!fgets(Name, sizeof Name, stdin))(à tout le moins, n'utilisez pas deux négations,! et! =)
4
@Roger Pate "n'utilisez pas deux négations" -> hmmm, si nous creusons profondément "ne pas" et "négation" sont deux négations . ;-). Peut-être "Use if (fgets(Name, sizeof Name, stdin)) {.
chux
3
@chux, je suis sûr que vous vouliez direif (fgets(Name, sizeof Name, stdin) == NULL ) {
R Sahu
@RSahu True : embêtant !:
chux

Réponses:

155

La manière légèrement laide:

char *pos;
if ((pos=strchr(Name, '\n')) != NULL)
    *pos = '\0';
else
    /* input too long for buffer, flag error */

La manière un peu étrange:

strtok(Name, "\n");

Notez que la strtokfonction ne fonctionne pas comme prévu si l'utilisateur entre une chaîne vide (c'est-à-dire qu'il appuie uniquement sur Entrée). Il laisse le \npersonnage intact.

Il y en a bien sûr d'autres également.

Jerry Coffin
la source
7
Toute bibliothèque d'exécution C qui est consciente des threads (c'est-à-dire la plupart de celles qui ciblent une plate-forme multi-thread), strtok()sera thread-safe (elle utilisera le stockage local des threads pour l'état 'inter-appel'). Cela dit, il est généralement préférable d'utiliser la strtok_r()variante non standard (mais assez courante) .
Michael Burr
2
Voir ma réponse pour une variante complètement thread-safe et réentrante, similaire à votre strtokapproche (et cela fonctionne avec des entrées vides). En fait, un bon moyen de mise en œuvre strtokconsiste à utiliser strcspnet strspn.
Tim Čas
2
Il est important de gérer le cas else si vous êtes dans un environnement où il y a un risque de lignes trop longues. Une entrée tronquée silencieusement peut provoquer des bogues très dommageables.
Malcolm McLean
2
Si vous aimez les monolignes et utilisez la glibc, essayez *strchrnul(Name, '\n') = '\0';.
twobit
Lorsque strchr(Name, '\n') == NULL, outre "l'entrée trop longue pour le tampon, erreur de drapeau", d'autres possibilités existent: le dernier texte de stdinne s'est pas terminé par un '\n'ou un rare caractère nul incorporé a été lu.
chux
440

Peut-être que la solution la plus simple utilise l'une de mes fonctions préférées les moins connues strcspn():

buffer[strcspn(buffer, "\n")] = 0;

Si vous souhaitez qu'il gère également '\r'(par exemple, si le flux est binaire):

buffer[strcspn(buffer, "\r\n")] = 0; // works for LF, CR, CRLF, LFCR, ...

La fonction compte le nombre de caractères jusqu'à ce qu'elle atteigne a '\r'ou a '\n'(en d'autres termes, elle trouve le premier '\r'ou '\n'). S'il ne touche rien, il s'arrête à '\0'(renvoyant la longueur de la chaîne).

Notez que cela fonctionne bien même s'il n'y a pas de nouvelle ligne, car strcspns'arrête à a '\0'. Dans ce cas, la ligne entière est simplement remplacée '\0'par '\0'.

Tim Čas
la source
30
Cela gère même les rares bufferque commence avec '\0', ce qui cause la douleur de l' buffer[strlen(buffer) - 1] = '\0';approche.
chux
5
@chux: Ouais, j'aurais aimé que plus de gens soient au courant strcspn(). IMO est l'une des fonctions les plus utiles de la bibliothèque. J'ai décidé d'écrire et de publier un tas de hacks C courants comme celui-ci aujourd'hui; une strtok_rimplémentation utilisant strcspnet a strspnété l'une des premières: codepad.org/2lBkZk0w ( Attention: je ne peux pas garantir que c'est sans bugs; il a été écrit à la hâte et en a probablement quelques-uns). Je ne sais pas encore où je vais les publier, cependant, mais j'ai l'intention de le faire dans l'esprit des fameux "hacks de twiddling".
Tim Čas
4
A cherché des moyens de couper solidement . Cela semble être le seul one-liner correct. est plus rapide - mais pas aussi simple. fgets()strcspn()strlen
chux
6
@sidbushes: La question, à la fois dans le titre et le contenu, pose des questions sur la nouvelle ligne defgets() fin d' entrée . Ce qui est toujours aussi la première nouvelle ligne.
Tim Čas
9
@sidbushes: je comprends d'où vous venez, mais je ne peux être tenu responsable des résultats de recherche Google pour des termes spécifiques. Parlez à Google, pas à moi.
Tim Čas
83
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n') 
    name[ln] = '\0';
James Morris
la source
8
Va probablement lancer une exception si la chaîne est vide, n'est-ce pas? Comme l'index hors de portée.
Edward Olamisan
1
@EdwardOlamisan, la chaîne ne sera cependant jamais vide.
James Morris
5
@James Morris Dans des cas inhabituels fgets(buf, size, ....)-> strlen(buf) == 0. 1) se fgets()lit comme le premier chara '\0'. 2) size == 13) fgets()renvoie NULLalors le bufcontenu pourrait être n'importe quoi. (Le code OP teste NULL cependant) size_t ln = strlen(name); if (ln > 0 && name[ln-1] == '\n') name[--ln] = '\0';
Suggère
2
Et si la chaîne est vide? lnserait -1, sauf que le fait size_tn'est pas signé, écrivant ainsi dans une mémoire aléatoire. Je pense que vous voulez utiliser ssize_tet vérifier lnest> 0.
abligh
2
@ legends2k: Une recherche d'une valeur au moment de la compilation (en particulier une valeur nulle comme dans strlen) peut être implémentée beaucoup plus efficacement qu'une recherche simple caractère par caractère. Pour cette raison, je considérerais cette solution meilleure que celles basées sur strchrou strcspn.
AnT
17

Vous trouverez ci-dessous une approche rapide pour supprimer un potentiel '\n'd'une chaîne enregistrée par fgets().
Il utilise strlen(), avec 2 tests.

char buffer[100];
if (fgets(buffer, sizeof buffer, stdin) != NULL) {

  size_t len = strlen(buffer);
  if (len > 0 && buffer[len-1] == '\n') {
    buffer[--len] = '\0';
  }

Maintenant, utilisez bufferet lenau besoin.

Cette méthode a l'avantage secondaire d'une lenvaleur pour le code suivant. Cela peut être facilement plus rapide que strchr(Name, '\n'). Réf YMMV, mais les deux méthodes fonctionnent.


buffer, à partir de l'original fgets()ne contiendra pas dans "\n"certaines circonstances:
A) La ligne était trop longue pour bufferque seulement le charprécédent '\n'soit enregistré dans buffer. Les caractères non lus restent dans le flux.
B) La dernière ligne du fichier ne s'est pas terminée par un '\n'.

Si l'entrée contient des caractères nuls '\0'quelque part, la longueur signalée par strlen()n'inclura pas l' '\n'emplacement.


Quelques autres questions de réponses:

  1. strtok(buffer, "\n");ne parvient pas à supprimer le '\n'quand bufferest "\n". De cette réponse - modifié après cette réponse pour avertir de cette limitation.

  2. Ce qui suit échoue en de rares occasions lorsque la première charlecture fgets()est '\0'. Cela se produit lorsque l'entrée commence par un imbriqué '\0'. Devient buffer[len -1]alors buffer[SIZE_MAX]accéder à la mémoire certainement en dehors de la plage légitime de buffer. Quelque chose qu'un pirate pourrait essayer ou trouver en lisant bêtement des fichiers texte UTF16. C'était l'état d'une réponse lorsque cette réponse a été écrite. Plus tard, un non-OP l'a édité pour inclure du code comme la vérification de cette réponse "".

    size_t len = strlen(buffer);
    if (buffer[len - 1] == '\n') {  // FAILS when len == 0
      buffer[len -1] = '\0';
    }
  3. sprintf(buffer,"%s",buffer);est un comportement indéfini: Réf . En outre, il n'enregistre aucun espace de début, de séparation ou de fin. Maintenant supprimé .

  4. [Modifier en raison d'une bonne réponse ultérieure ] Il n'y a aucun problème avec la doublure buffer[strcspn(buffer, "\n")] = 0;autre que les performances par rapport à l' strlen()approche. Les performances de découpage ne sont généralement pas un problème étant donné que le code fait des E / S - un trou noir du temps CPU. Si le code suivant nécessite la longueur de la chaîne ou est très sensible aux performances, utilisez cette strlen()approche. Sinon, strcspn()c'est une bonne alternative.

chux - Réintégrer Monica
la source
Merci pour la réponse utile. Pouvons-nous utiliser strlen(buffer)lorsque la taille du tampon est allouée dynamiquement en utilisant malloc?
rrz0
@ Rrz0 buffer = malloc(allocation_size); length = strlen(buffer);est mauvais - les données de la mémoire pointées par buffersont inconnues. buffer = malloc(allocation_size_4_or_more); strcpy(buffer, "abc"); length = strlen(buffer);est OK
chux
Merci pour cela!! je prends un cours de CS et cela a été très utile pour l'une des tâches. j'ai crédité votre réponse dans le code source.
Nathaniel Hoyt
8

Direct pour supprimer le '\ n' de la sortie fgets si chaque ligne a '\ n'

line[strlen(line) - 1] = '\0';

Autrement:

void remove_newline_ch(char *line)
{
    int new_line = strlen(line) -1;
    if (line[new_line] == '\n')
        line[new_line] = '\0';
}
Amitabha
la source
1
Notez qu'il serait plus sûr d'utiliser à la strnlenplace de strlen.
Mike Mertsock
3
Un commentaire à la première réponse dans la question liée indique "Notez que strlen (), strcmp () et strdup () sont sûrs. Les alternatives 'n' vous offrent des fonctionnalités supplémentaires."
Étienne
4
@esker non, ce ne serait pas le cas. insérer un nn'augmente pas comme par magie la sécurité, dans ce cas cela rendrait en fait le code plus dangereux. De même avec strncpy, une fonction terriblement dangereuse. Le message auquel vous avez lié est un mauvais conseil.
MM
3
Cela échoue lamentablement pour une chaîne vide ( ""). Aussi strlen()retourne size_tpas int.
Alk
4
ce n'est pas sûr pour une chaîne vide, il écrira à l'index -1. Ne l'utilisez pas.
Jean-François Fabre
3

Pour un découpage '\ n' unique,

void remove_new_line(char* string)
{
    size_t length = strlen(string);
    if((length > 0) && (string[length-1] == '\n'))
    {
        string[length-1] ='\0';
    }
}

pour un découpage "\ n" multiple,

void remove_multi_new_line(char* string)
{
  size_t length = strlen(string);
  while((length>0) && (string[length-1] == '\n'))
  {
      --length;
      string[length] ='\0';
  }
}
BEPP
la source
1
Pourquoi imbriquer ifquand vous pouvez simplement écrire une condition en utilisant &&? Cette whileboucle a une structure étrange; ça pourrait être tout simplement while (length > 0 && string[length-1] == '\n') { --length; string[length] = '\0'; }.
melpomene
@melpomene merci pour la suggestion. Mettez à jour le code.
BEPP
1
Je suggère que la première fonction est plus naturellement définie comme suit: size_t length = strlen(string); if (length > 0 && string[length-1] == '\n') { string[length-1] = '\0'; }. Cela reflète également mieux la deuxième définition (en utilisant simplement ifau lieu de while).
melpomene
@elpomene merci. Ca a du sens. J'ai mis à jour le code.
BEPP
1

My Newbie way ;-) Veuillez me faire savoir si c'est correct. Il semble fonctionner pour tous mes cas:

#define IPT_SIZE 5

int findNULL(char* arr)
{
    for (int i = 0; i < strlen(arr); i++)
    {
        if (*(arr+i) == '\n')
        {
            return i;
        }
    }
    return 0;
}

int main()
{
    char *input = malloc(IPT_SIZE + 1 * sizeof(char)), buff;
    int counter = 0;

    //prompt user for the input:
    printf("input string no longer than %i characters: ", IPT_SIZE);
    do
    {
        fgets(input, 1000, stdin);
        *(input + findNULL(input)) = '\0';
        if (strlen(input) > IPT_SIZE)
        {
            printf("error! the given string is too large. try again...\n");
            counter++;
        }
        //if the counter exceeds 3, exit the program (custom function):
        errorMsgExit(counter, 3); 
    }
    while (strlen(input) > IPT_SIZE);

//rest of the program follows

free(input)
return 0;
}
Duck Ling
la source
1

Les étapes pour supprimer le caractère de nouvelle ligne de la manière peut-être la plus évidente:

  1. Déterminez la longueur de la chaîne à l'intérieur NAMEen utilisant strlen(), header string.h. Notez que strlen()cela ne compte pas la terminaison \0.
size_t sl = strlen(NAME);

  1. Vérifiez si la chaîne commence par ou ne comprend qu'un seul \0caractère (chaîne vide). Dans ce cas sl, 0car strlen()comme je l'ai dit ci-dessus ne compte pas le \0et s'arrête à sa première occurrence:
if(sl == 0)
{
   // Skip the newline replacement process.
}

  1. Vérifiez si le dernier caractère de la chaîne appropriée est un caractère de nouvelle ligne '\n'. Si tel est le cas, remplacez-le \npar un \0. Notez que le nombre d'index commence à 0donc nous devrons faire NAME[sl - 1]:
if(NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

Notez que si vous avez uniquement appuyé sur Entrée à la fgets()demande de chaîne (le contenu de la chaîne était uniquement composé d'un caractère de nouvelle ligne), la chaîne en NAMEsera une chaîne vide par la suite.


  1. Nous pouvons combiner les étapes 2. et 3. ensemble en une seule ifdéclaration en utilisant l'opérateur logique &&:
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

  1. Le code fini:
size_t sl = strlen(NAME);
if(sl > 0 && NAME[sl - 1] == '\n')
{
   NAME[sl - 1] = '\0';
}

Si vous aimez plutôt une fonction pour utiliser cette technique en gérant fgetsles chaînes de sortie en général sans retaper à chaque fois, voici fgets_newline_kill:

void fgets_newline_kill(char a[])
{
    size_t sl = strlen(a);

    if(sl > 0 && a[sl - 1] == '\n')
    {
       a[sl - 1] = '\0';
    }
}

Dans votre exemple fourni, ce serait:

printf("Enter your Name: ");

if (fgets(Name, sizeof Name, stdin) == NULL) {
    fprintf(stderr, "Error reading Name.\n");
    exit(1);
}
else {
    fgets_newline_kill(NAME);
}

Notez que cette méthode ne fonctionne pas si la chaîne d'entrée contient des \0s incorporés . Si tel était le cas strlen(), le nombre de caractères ne serait renvoyé que jusqu'au premier \0. Mais ce n'est pas une approche assez courante, car la plupart des fonctions de lecture de chaîne s'arrêtent généralement au premier \0et prennent la chaîne jusqu'à ce caractère nul.

Mis à part la question seule. Essayez d'éviter la double négations qui font votre code unclearer: if (!(fgets(Name, sizeof Name, stdin) != NULL) {}. Vous pouvez simplement le faire if (fgets(Name, sizeof Name, stdin) == NULL) {}.

RobertS soutient Monica Cellio
la source
Je ne sais pas pourquoi vous voudriez faire ça. Le but de la suppression des sauts de ligne n'est pas de mettre fin aux chaînes nulles; c'est pour supprimer les nouvelles lignes. Remplacer un \npar un \0à la fin d'une chaîne est un moyen de "supprimer" la nouvelle ligne. Mais le remplacement de \ncaractères dans une chaîne change fondamentalement la chaîne. Il n'est pas rare d'avoir des chaînes avec plusieurs caractères de nouvelle ligne intentionnels, et cela couperait effectivement les extrémités de ces chaînes. Pour supprimer ces nouvelles lignes, le contenu du tableau doit être déplacé vers la gauche pour remplacer le \n.
ex nihilo
@exnihilo Comment quelqu'un peut-il entrer une chaîne avec plusieurs sauts de ligne à l'intérieur en utilisant fgets()?
RobertS soutient Monica Cellio
Eh bien, vous pouvez concaténer des chaînes obtenues par plusieurs appels à fgets(). Mais je ne comprends pas votre objection: c'est vous qui proposez du code pour gérer plusieurs sauts de ligne.
ex nihilo
@exnihilo Vous avez raison, je repenserai la stratégie. Je voulais juste ajouter une manière très dure mais possible d'obtenir le résultat souhaité.
RobertS soutient Monica Cellio
@exnihilo J'ai édité ma réponse complètement et j'ai suivi l'approche principale en utilisant strlenetc. Justification de ne pas être un doublon: 1. Explication du code par étapes. 2. Fourni comme une fonction et une solution contextuelle. 3. Astuce pour éviter les expressions de double négation.
RobertS soutient Monica Cellio
0

Tim Čas one liner est étonnant pour les cordes obtenues par un appel aux fgets, car vous savez qu'ils contiennent une seule nouvelle ligne à la fin.

Si vous êtes dans un contexte différent et que vous souhaitez gérer des chaînes pouvant contenir plusieurs sauts de ligne, vous recherchez peut-être strrspn. Ce n'est pas POSIX, ce qui signifie que vous ne le trouverez pas sur tous les Unices. J'en ai écrit un pour mes propres besoins.

/* Returns the length of the segment leading to the last 
   characters of s in accept. */
size_t strrspn (const char *s, const char *accept)
{
  const char *ch;
  size_t len = strlen(s);

more: 
  if (len > 0) {
    for (ch = accept ; *ch != 0 ; ch++) {
      if (s[len - 1] == *ch) {
        len--;
        goto more;
      }
    }
  }
  return len;
}

Pour ceux qui recherchent un équivalent de chomp Perl en C, je pense que c'est ça (chomp ne supprime que la nouvelle ligne de fin).

line[strrspn(string, "\r\n")] = 0;

La fonction strrcspn:

/* Returns the length of the segment leading to the last 
   character of reject in s. */
size_t strrcspn (const char *s, const char *reject)
{
  const char *ch;
  size_t len = strlen(s);
  size_t origlen = len;

  while (len > 0) {
    for (ch = reject ; *ch != 0 ; ch++) {
      if (s[len - 1] == *ch) {
        return len;
      }
    }
    len--;
  }
  return origlen;
}
Philippe A.
la source
1
"parce que vous savez qu'ils contiennent une seule nouvelle ligne à la fin." -> Cela fonctionne même quand il n'y en a pas '\n'(ou si la chaîne l'est "").
chux
En réponse à votre premier commentaire chux, ma réponse le conserve. J'ai dû jeter resetlen strrcspnpour quand il n'y a pas \n.
Philippe A.
Pourquoi utiliser goto end;au lieu de return len;?
chqrlie
@chqrlie J'avais besoin de sortir de cette boucle inélégante à 2 niveaux dans laquelle je me suis engagé. Le mal a été fait. Pourquoi pas un goto?
Philippe A.
Vous avez deux types de gotos dans votre code: un inutile gotoqui peut être remplacé par une returndéclaration et un arrière gotoqui est considéré comme mauvais. L'utilisation strchraide à implémenter strrspnet strrcspnde manière plus simple: size_t strrspn(const char *s, const char *accept) { size_t len = strlen(s); while (len > 0 && strchr(accept, s[len - 1])) { len--; } return len; }etsize_t strrcspn(const char *s, const char *reject) { size_t len = strlen(s); while (len > 0 && !strchr(reject, s[len - 1])) { len--; } return len; }
chqrlie
0

Si l'utilisation getlineest une option - sans négliger ses problèmes de sécurité et si vous souhaitez renforcer les pointeurs - vous pouvez éviter les fonctions de chaîne car la getlinerenvoie le nombre de caractères. Quelque chose comme ci-dessous

#include<stdio.h>
#include<stdlib.h>
int main(){
char *fname,*lname;
size_t size=32,nchar; // Max size of strings and number of characters read
fname=malloc(size*sizeof *fname);
lname=malloc(size*sizeof *lname);
if(NULL == fname || NULL == lname){
 printf("Error in memory allocation.");
 exit(1);
}
printf("Enter first name ");
nchar=getline(&fname,&size,stdin);
if(nchar == -1){ // getline return -1 on failure to read a line.
 printf("Line couldn't be read.."); 
 // This if block could be repeated for next getline too
 exit(1);
}
printf("Number of characters read :%zu\n",nchar);
fname[nchar-1]='\0';
printf("Enter last name ");
nchar=getline(&lname,&size,stdin);
printf("Number of characters read :%zu\n",nchar);
lname[nchar-1]='\0';
printf("Name entered %s %s\n",fname,lname);
return 0;
}

Remarque : Les [ problèmes de sécurité ] avec getlinene doivent pas être négligés cependant.

sjsam
la source
-1

La fonction ci-dessous fait partie de la bibliothèque de traitement de chaînes que je gère sur Github. Il supprime et les caractères indésirables d'une chaîne, exactement ce que vous voulez

int zstring_search_chr(const char *token,char s){
    if (!token || s=='\0')
        return 0;

    for (;*token; token++)
        if (*token == s)
            return 1;

    return 0;
}

char *zstring_remove_chr(char *str,const char *bad) {
    char *src = str , *dst = str;
    while(*src)
        if(zstring_search_chr(bad,*src))
            src++;
        else
            *dst++ = *src++;  /* assign first, then incement */

    *dst='\0';
        return str;
}

Un exemple d'utilisation pourrait être

Example Usage
      char s[]="this is a trial string to test the function.";
      char const *d=" .";
      printf("%s\n",zstring_remove_chr(s,d));

  Example Output
      thisisatrialstringtotestthefunction

Vous voudrez peut-être vérifier d'autres fonctions disponibles, ou même contribuer au projet :) https://github.com/fnoyanisi/zString

fnisi
la source
Vous devez supprimer le *in *src++;et faire bad, tokenet d const char *. Aussi pourquoi ne pas utiliser à la strchrplace de zChrSearch? *srcne peut pas être '\0'dans votre zStrrmvfonction.
chqrlie
Merci @chqrlie! mis à jour le code pour refléter vos suggestions ..... zstring a commencé comme un projet amusant dans le but de créer une bibliothèque de manipulation de chaînes sans utiliser de fonctions de bibliothèque standard, donc je n'ai pas utiliséstrchr
fnisi
1
Écrire une " bibliothèque de manipulation de chaînes sans utiliser de fonctions de bibliothèque standard " est un bon exercice, mais pourquoi dire aux autres de l'utiliser? Si quoi que ce soit, ça va être plus lent et moins testé que n'importe quelle bibliothèque standard.
melpomene
Cela fait un travail différent de ce que la question pose. Il peut probablement être utilisé pour se débarrasser de la seule nouvelle ligne, mais cela semble exagéré.
Jonathan Leffler
-1
 for(int i = 0; i < strlen(Name); i++ )
{
    if(Name[i] == '\n') Name[i] = '\0';
}

Tu devrais essayer. Ce code parcourt en boucle la chaîne jusqu'à ce qu'il trouve le '\ n'. Lorsqu'il est trouvé, le '\ n' sera remplacé par le terminateur de caractère nul '\ 0'

Notez que vous comparez des caractères et non des chaînes dans cette ligne, il n'est donc pas nécessaire d'utiliser strcmp ():

if(Name[i] == '\n') Name[i] = '\0';

puisque vous utiliserez des guillemets simples et non des guillemets doubles. Voici un lien sur les guillemets simples vs doubles si vous voulez en savoir plus

Matheus Martins Jerônimo
la source
2
ce serait mieux si vous expliquez et éditez le format de votre code.
Anh Pham
Habituellement, il vaut mieux expliquer une solution au lieu de simplement publier quelques lignes de code anonyme. Vous pouvez lire Comment écrire une bonne réponse , et aussi Expliquer les réponses entièrement basées sur du code .
Massimiliano Kraus
1
Je suis désolé, c'était ma première contribution ici. Je le réparerai. Merci pour les commentaires
Matheus Martins Jerônimo
3
Inefficace: for(int i = 0; i < strlen(Name); i++ )appellera strlen(Name)plusieurs fois (changements de boucle Name[]) donc avec une longueur N, c'est une O(N*N)solution. Un seul appel à strlen(Name), le cas échéant, est nécessaire pour fournir une solution O (N) `. On ne sait pas pourquoi int iest utilisé à la place de size_t i. Considérezfor(size_t i = 0; i < Name[i]; i++ )
chux
@chux Plus commefor (size_t i = 0; Name[i]; i++) { if (Name[i] == '\n') { Name[i] = '\0'; break; } }
melpomene
-1

Essaye celui-là:

        int remove_cr_lf(char *str)
        {
          int len =0;


          len = strlen(str);

          for(int i=0;i<5;i++)
          {
            if (len>0)
            if (str[len-1] == '\n')
            {
              str[len-1] = 0;
              len--;
            }

            if (len>0)
            if (str[len-1] == '\r')
            {
              str[len-1] = 0;
              len--;
            }
          }

          return 0;
        }
Balazs Kiss
la source
1
len = strlen(str)peut déborder: strlenretournesize_t pas int. Qu'en est-il des if (len>0) if (...)conditions étranges ? Tu ne sais pas &&? Si vous comptez supprimer plusieurs instances finales de CR / LF, pourquoi vous limiter à 5? Pourquoi ne pas les supprimer tous? Pourquoi la fonction a-t-elle un inttype de retour alors qu'elle revient toujours 0? Pourquoi ne pas simplement revenir void?
melpomene