Question Suppression du caractère de nouvelle ligne à partir de l'entrée fgets ()


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 une nouvelle ligne \n caractère à la fin. Donc si j'entre John ça finit par envoyer John\n. Comment puis-je supprimer cette \n et envoyer une chaîne appropriée.


162
2018-04-22 19:21


origine


Réponses:


La façon un peu 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 le strtok fonction ne fonctionne pas comme prévu si l'utilisateur entre une chaîne vide (c'est-à-dire appuie uniquement sur Entrée). Il laisse le \n caractère intact.

Il y en a d'autres aussi, bien sûr.


112
2018-04-22 19:26



Peut-être la solution la plus simple utilise-t-elle une de mes fonctions préférées peu connues, strcspn():

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

Si vous le voulez aussi gérer '\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 '\r' ou un '\n' (autrement dit, il trouve le premier '\r' ou '\n'). S'il ne frappe rien, il s'arrête au '\0' (retourne la longueur de la chaîne).

Notez que cela fonctionne bien même s'il n'y a pas de nouvelle ligne, car strcspn s'arrête à un '\0'. Dans ce cas, la ligne entière remplace simplement '\0' avec '\0'.


297
2018-02-11 18:54



size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n') 
    name[ln] = '\0';

77
2018-04-22 19:26



Ci-dessous, une approche rapide pour supprimer un potentiel '\n' à partir 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 buffer et len comme requis.

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


buffer, de l'original fgets() ne contiendra pas dans "\n" dans certaines circonstances:
A) La ligne était trop longue pour buffer donc seulement char précédant le '\n' est 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 comporte des caractères nuls incorporés '\0' dans quelque part, la longueur signalée par strlen() ne comprendra pas le '\n' emplacement.


Quelques autres réponses aux problèmes:

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

  2. Ce qui suit échoue à de rares occasions lorsque le premier char lu par fgets() est '\0'. Cela se produit lorsque l’entrée commence par une '\0'. alors buffer[len -1] devient buffer[SIZE_MAX] accéder à la mémoire certainement en dehors de la gamme légitime de buffer. Quelque chose qu'un pirate informatique peut essayer ou trouver en lisant bêtement des fichiers texte UTF16. C'était l'état d'un répondre quand cette réponse a été écrite. Plus tard, un non-OP a édité pour inclure le code comme cette réponse vérifie pour "".

    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: Ref. De plus, il ne sauvegarde aucun espace de début, de séparation ou de fin. À présent supprimé.

  4. [Modifier en raison de bien plus tard répondre] Il n'y a pas de problèmes avec le 1 liner buffer[strcspn(buffer, "\n")] = 0; autre que la performance par rapport à la strlen()approche. Les performances lors du découpage ne sont généralement pas un problème étant donné que le code fait des E / S - un trou noir de temps CPU. Si le code suivant a besoin de la longueur de la chaîne ou est très sensible aux performances, utilisez-le strlen() approche. Sinon le strcspn() est une bonne alternative.


15
2018-01-01 10:29



Direct pour supprimer le '\ n' de la sortie de 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';
}

5
2018-06-30 01:15



Pour single '\ n' trmming,

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

pour le rognage multiple,

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

}

1
2018-03-16 05:45



 for(int i = 0; i < strlen(Name); i++ )
{
    if(Name[i] == '\n') Name[i] = '\0';
}

Tu devrais essayer. Ce code passe en boucle dans la chaîne jusqu'à ce qu'il trouve le "\ n". Quand il trouve le '\ n' sera remplacé par le caractère de fin de caractère nul '\ 0'

Notez que vous comparez des caractères et non des chaînes de caractères sur cette ligne, vous n'avez donc pas besoin 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 et doubles si vous voulez en savoir plus


1
2017-09-17 12:21



char name[1024];
unsigned int len;

printf("Enter your name: ");
fflush(stdout);
if (fgets(name, sizeof(name), stdin) == NULL) {
    fprintf(stderr, "error reading name\n");
    exit(1);
}
len = strlen(name);
if (name[len - 1] == '\n')
    name[len - 1] = '\0';

0
2018-04-22 19:30



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


0
2018-02-18 00:41