
sfactor
Estoy tratando de obtener algunos datos del usuario y enviarlos a otra función en gcc. El código es algo como esto.
printf("Enter your Name: ");
if (!(fgets(Name, sizeof Name, stdin) != NULL)) {
fprintf(stderr, "Error reading Name.\n");
exit(1);
}
Sin embargo, encuentro que tiene una nueva línea. \n
personaje al final. Entonces si entro John
termina enviando John\n
. como elimino eso \n
y enviar una cadena adecuada.

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

chux – Reincorporar a Monica
A continuación se muestra un enfoque rápido para eliminar un potencial '\n'
de una cadena guardada por fgets()
.
Usa strlen()
con 2 pruebas.
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';
}
Ahora usa buffer
y len
según sea necesario.
Este método tiene el beneficio adicional de un len
valor para el código subsiguiente. Puede ser fácilmente más rápido que strchr(Name, '\n')
. Árbitro YMMV, pero ambos métodos funcionan.
buffer
del original fgets()
no contendrá en "\n"
bajo algunas circunstancias:
A) La fila era demasiado larga para buffer
tan solo char
precediendo al '\n'
se guarda en buffer
. Los caracteres no leídos permanecen en la transmisión.
B) La última línea del archivo no terminaba con un '\n'
.
Si la entrada tiene caracteres nulos incrustados '\0'
en alguna parte, la longitud reportada por strlen()
no incluirá el '\n'
localización.
Algunos otros problemas de respuestas:
-
strtok(buffer, "\n");
no logra eliminar el '\n'
cuando buffer
es "\n"
. De esta respuesta, modificada después de esta respuesta para advertir sobre esta limitación.
-
Lo siguiente falla en raras ocasiones cuando el primero char
Leído por fgets()
es '\0'
. Esto sucede cuando la entrada comienza con un incrustado '\0'
. Entonces buffer[len -1]
se convierte buffer[SIZE_MAX]
acceder a la memoria ciertamente fuera del rango legítimo de buffer
. Algo que un hacker puede intentar o encontrar al leer tontamente archivos de texto UTF16. Este era el estado de una respuesta cuando se escribió esta respuesta. Más tarde, un no OP lo editó para incluir un código como el cheque de esta respuesta para ""
.
size_t len = strlen(buffer);
if (buffer[len - 1] == '\n') { // FAILS when len == 0
buffer[len -1] = '\0';
}
-
sprintf(buffer,"%s",buffer);
es un comportamiento indefinido: Ref. Además, no guarda ningún espacio en blanco inicial, separador o final. Ahora eliminado.
-
[Edit due to good later answer] No hay problemas con el 1 liner. buffer[strcspn(buffer, "\n")] = 0;
aparte del rendimiento en comparación con el strlen()
Acercarse. El rendimiento en el recorte generalmente no es un problema dado que el código está haciendo E / S, un agujero negro del tiempo de CPU. Si el siguiente código necesita la longitud de la cadena o es muy consciente del rendimiento, use este strlen()
Acercarse. De lo contrario, el strcspn()
es una buena alternativa.

Amitabha
Directo para eliminar el ‘\n’ de la salida de fgets si cada línea tiene ‘\n’
line[strlen(line) - 1] = '\0';
De lo contrario:
void remove_newline_ch(char *line)
{
int new_line = strlen(line) -1;
if (line[new_line] == '\n')
line[new_line] = '\0';
}
En general, en lugar de recortar los datos que no desea, evite escribirlos en primer lugar. Si no desea la nueva línea en el búfer, no use fgets. En su lugar, utiliza getc
o fgetc
o scanf
. Tal vez algo como:
#include <stdio.h>
#include <stdlib.h>
int
main(void)
{
char Name[256];
char fmt[32];
if( snprintf(fmt, sizeof fmt, "%%%zd[^\n]", sizeof Name - 1) >= (int)sizeof fmt ){
fprintf(stderr, "Unable to write format\n");
return EXIT_FAILURE;
}
if( scanf(fmt, Name) == 1 ) {
printf("Name = %s\n", Name);
}
return 0;
}
Tenga en cuenta que este enfoque particular dejará la nueva línea sin leer, por lo que es posible que desee utilizar una cadena de formato como "%255[^\n]%*c"
descartarlo (por ejemplo, sprintf(fmt, "%%%zd[^\n]%%*c", sizeof Name - 1);
), o tal vez seguir el scanf con un getchar()
.
if (!fgets(Name, sizeof Name, stdin))
(como mínimo, no utilice dos negaciones, ! y !=)– Roger Paté
22 de abril de 2010 a las 20:05
@Roger Pate “no use dos negaciones” –> hmmm, si profundizamos, “no” y “negación” son ambos negaciones. ;-). Tal vez “Usar
if (fgets(Name, sizeof Name, stdin)) {
.– chux – Reincorporar a Monica
24 de agosto de 2016 a las 14:53
@chux, estoy seguro de que quisiste decir
if (fgets(Name, sizeof Name, stdin) == NULL ) {
– R Sahu
5 abr 2018 a las 18:50
@RSahu Cierto: molesto
!
:– chux – Reincorporar a Monica
5 abr 2018 a las 19:30