(Consulta) [C] ¿Usar los corchetes para delimitar caracteres es ANSI?

Iniciado por class_OpenGL, 15 Junio 2016, 08:39 AM

0 Miembros y 1 Visitante están viendo este tema.

class_OpenGL

Hola, muy buenas. Quería preguntar en base al siguiente código:

#include <stdio.h>

int main() {
char cadena[16];

fscanf(stdin, "%s[^16]", cadena);
fprintf(stdout, cadena);

return 0;
}


En este código, uso %s[^16] para delimitar los caracteres que puede tener la cadena, pero al probar este código y probando con cadenas mayores a 16 caracteres, el programa me daba error de segmentation fault (me lo ha dicho el debugger del MinGW-w64). Esto me lleva a la siguiente pregunta: ¿usar esta manera para delimitar los caracteres es ANSI, o solo está disponible para solo ciertos compiladores?

Gracias :D

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

AlbertoBSD

#1
Hola te soy sincero no habia visto antes esa forma de limitar la cantidad leida en fscanf...

Por ejemplo esta para delimitar la salida de fprintf con "%.8X" cantidad de hexadecimales a imprimir.

Busque referencias al respecto mientras resolvíamos el otro Topic. De hecho estaba asi:



Tendras alguna fuente donde hablen del formato que en la vaga busqueda que hice no encontre nada.

Saludos



Edito he vuelto a buscar y encontre

http://stackoverflow.com/questions/1247989/how-do-you-allow-spaces-to-be-entered-using-scanf

Donde reiteran el uso de fgets y aun no veo nada de ese formato de cadena

Saludos
Donaciones
1Coffee1jV4gB5gaXfHgSHDz9xx9QSECVW

class_OpenGL

Ehmmm tampoco hacía falta excederse xD. Gracias por la info. Cambiaré de fuente :P Estoy aprendiendo C y no puedo saber qué es verídico y que no.

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

MAFUS

Para limitar el número de caracteres se usa un entero, que representa el número máximo de caracteres a recoger, entre % y s.

scanf("%5s", cadena);

La técnica de los corchetes es para asegurarse que la cadena solo recoge esos caracteres.

scanf("%[abc]", cadena);

Leerá caracteres hasta que encuentre uno que no sea a, b, o c; en ese momento se detendrá sin recoger ese valor no válido. Cuidado: la cadena a recoger debe empezar al menos, con uno de esos caracteres, sino no está definido su comportamiento.

De igual forma se puede hacer que scanf vaya recogiendo caracteres hasta encontrarse uno de los caracteres de la lista.

scanf("%[^abc]", cadena);

Así, mientras va leyendo encuentra a, b o c, se va a detener sin recoger ese carácter.

Es sustituto de gets, sin el inconveniente de que recoge el caracter '\n' lo siguiente:

scanf("%[^'\n']", cadena);

Pues recogerá, también, espacios y tabulaciones. Si se usa el entero delimitador de caracteres se tiene la seguridad de no sobrepasar el buffer:

scanf("%16[^'\n']", cadena);




Si no trabajas con linux u otro *nix y puedes hacer uso de 'man' en tu consola, escribe 'man <nombre_de_funcion>' en tu buscador de internet. Te llevará rápidamente a las páginas de los manuales de estos SS.OO. que también están publicadas en la red.

class_OpenGL

#4
Vale!!! Muchas gracias :D




¿Podría hacer fscanf(archivo, "%s['\n'' '", cadena)? (Nótese el espacio entre ' ')

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

class_OpenGL

¿Podría hacer fscanf(archivo, "%s['\n'' '", cadena)? (Nótese el espacio entre ' ')

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL

MAFUS

Bueno, la cadena de control no empieza por %s sino por %[.
Así como lo has puesto lo que va a hacer es recoger una cadena hasta el primer espacio/tabulador/nueva linea, después esperará los caracteres ['\n'' ' y los descartará (si aparecen otros caracteres que no sean esos el comportamiento no está definido.
De igual forma cuándo abres unos corchetes debes cerrarlos. Así la cadena de control que pretendes construir es:
%['\n' ] Nótese que hay un espacio entre el carácter de nueva línea y el corchete.
Esto hará la función espere una cadena formada por caracteres nueva línea y espacio y, al menos, deberá empezar por uno de estos dos. Cuándo se encuentre con otros caracteres distintos se detendrá.
Si lo que quieres es que capture toda la cadena hasta encontrar uno de estos caracteres debes negar esa cadena mediante el operador ^. Así:
%[^'\n' ]

class_OpenGL

Vaya, cuantos detalles. Si, tienes toda la razón. Estoy de un despistado... xD

Programador aficionado. Me quiero centrar en programar videojuegos. La API que uso para crearlos es OpenGL