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.
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.
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"'
.
size_t ln = strlen(name) - 1;
if (*name && name[ln] == '\n')
name[ln] = '"151900920"';
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:
-
strtok(buffer, "\n");
omet d'enlever le'\n'
alors quebuffer
est"\n"
. De cette réponse - modifié après cette réponse pour prévenir de cette limitation. -
échoue en de rares occasions, lors de la première
char
lu parfgets()
est'"1519170920"'
. Cela se produit lorsque l'entrée commence par un'"1519170920"'
intégré . Puisbuffer[len -1]
devientbuffer[SIZE_MAX]
accéder à la mémoire certainement en dehors de la portée légitime debuffer
. 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"'; }
-
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é . -
[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'approchestrlen()
. 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 approchestrlen()
. Sinon lestrcspn()
est une bonne alternative.
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"';
}
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"';
}
}
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;
}
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
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.
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"';
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
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;
}