Suppression du caractère de fin de ligne 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 cela.

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

163
demandé sur Jonathan Leffler 2010-04-22 23:21:18

12 réponses

Le un peu moche:

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

Le un peu étrange façon:

strtok(Name, "\n");

notez que la fonction strtok ne fonctionne pas comme prévu si l'utilisateur entre une chaîne vide (c'est-à-dire appuie seulement sur Entrée). Il laisse intact le caractère \n .

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

113
répondu Jerry Coffin 2017-01-08 18:54:04

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

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

si vous voulez qu'il traite aussi '\r' (dire, 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 un '\r' ou un '\n' (en d'autres termes, elle trouve le premier '\r' ou '\n' ). Si il n'a pas touché quoi que ce soit, il s'arrête au '"151980920"' (retour de la longueur de la corde).

notez que cela fonctionne très bien même s'il n'y a pas de nouvelle ligne, parce que strcspn s'arrête à un '" 151980920"' . Dans ce cas, la ligne entière remplace simplement '"151980920"' par '"151980920"' .

307
répondu Tim Čas 2015-02-11 18:54:56
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n') 
    name[ln] = '"151900920"';
78
répondu James Morris 2015-12-31 18:55:26

ci-dessous est une approche rapide pour supprimer un potentiel '\n' d'une chaîne de caractères sauvegardé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] = '"151900920"';
  }

utilisez maintenant buffer et len au besoin.

cette méthode présente l'avantage latéral d'une valeur de len pour le code suivant. Il peut être facilement plus rapide que strchr(Name, '\n') . Ref YMMV, mais les deux méthodes de travail.


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 se termine pas par un '\n' .

si input a les caractères nuls '"1519170920"' y sont quelque part, la longueur rapportée par strlen() n'inclut pas l'emplacement '\n' .


Quelques autres réponses " questions:

  1. strtok(buffer, "\n"); omet d'enlever le '\n' alors que buffer est "\n" . De cette réponse - modifié après cette réponse pour prévenir de cette limitation.

  2. échoue en de rares occasions, lors de la première char lu par fgets() est '"1519170920"' . Cela se produit lorsque l'entrée commence par un '"1519170920"' intégré . Puis buffer[len -1] devient buffer[SIZE_MAX] accéder à la mémoire certainement en dehors de la portée légitime de buffer . Quelque chose qu'un hacker peut 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é écrit. Plus tard, un non-OP l'a modifié pour inclure le code comme la vérification de cette réponse pour "" .

    size_t len = strlen(buffer);
    if (buffer[len - 1] == '\n') {  // FAILS when len == 0
      buffer[len -1] = '"151910920"';
    }
    
  3. sprintf(buffer,"%s",buffer); est un comportement non défini: Ref . De plus, il ne sauve aucun espace menant, séparant ou traînant. Maintenant supprimé .

  4. [Modifier en raison de la bonne plus tard réponse ] Il n'y a pas de problèmes avec les 1 liner buffer[strcspn(buffer, "\n")] = 0; autre que la performance par rapport à l'approche strlen() . La Performance dans l'ébarbage n'est généralement pas un problème étant donné que le code fait un trou noir de temps CPU. Si le code suivant a besoin de la longueur de la chaîne ou est très soucieux de performance, utilisez cette approche strlen() . Sinon le strcspn() est une bonne alternative.

15
répondu chux 2017-12-06 22:45:02

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

line[strlen(line) - 1] = '"151900920"';

autrement:

void remove_newline_ch(char *line)
{
    int new_line = strlen(line) -1;
    if (line[new_line] == '\n')
        line[new_line] = '"151910920"';
}
4
répondu Amitabha 2013-06-30 01:15:09

For single '\n 'trmming,

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

pour de multiples '\n' parage,

void remove_multi_new_line(char* string)
{
  size_t length = strlen(string);
  while((length>0) && (string[length-1] == '\n'))
  {
      --length;
      string[length] ='"151910920"';
  }
}
1
répondu Naveen Kumar 2018-09-18 06:58:59

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

si vous êtes dans un contexte différent et que vous voulez gérer des chaînes qui peuvent contenir plus d'une nouvelle ligne, vous pourriez être à la recherche de strrspn. Il n'est pas POSIX, ce qui signifie que vous ne le trouverez pas sur toutes les Unices. Je l'ai écrit 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 cherchent un équivalent Perl chomp en C, je pense c'est ça (chomp ne supprime que la ligne suivante).

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;
}
0
répondu Philippe A. 2016-11-30 20:17:19
 for(int i = 0; i < strlen(Name); i++ )
{
    if(Name[i] == '\n') Name[i] = '"151900920"';
}

vous devriez essayer. Ce code boucle la chaîne de caractères jusqu'à ce qu'il trouve le '\N'. Quand il est trouvé le '\N' sera remplacé par le caractère nul terminator '\0 '

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

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

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

0
répondu Matheus Martins Jerônimo 2017-09-17 23:22:14

si l'utilisation de getline est une option - ne négligeant pas ses problèmes de sécurité et si vous souhaitez attacher des pointeurs - vous pouvez éviter les fonctions de chaîne de caractères comme le getline renvoie 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]='"151900920"';
printf("Enter last name ");
nchar=getline(&lname,&size,stdin);
printf("Number of characters read :%zu\n",nchar);
lname[nchar-1]='"151900920"';
printf("Name entered %s %s\n",fname,lname);
return 0;
}

Note : le [ questions de sécurité ] avec getline ne devrait pas être négligé cependant.

0
répondu sjsam 2017-12-07 06:16:36
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] = '"151900920"';
-1
répondu draebek 2010-04-22 19:30:18

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

int zstring_search_chr(const char *token,char s){
    if (!token || s=='"151900920"')
        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='"151900920"';
        return str;
}

un exemple d'usage 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 pouvez vérifier d'autres fonctions disponibles, ou même contribuer au projet :) https://github.com/fnoyanisi/zString

-1
répondu Fehmi Noyan ISI 2016-10-21 08:29:03

essayez celui-ci:

        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;
        }
-1
répondu Balazs Kiss 2018-05-09 13:38:40