Discussion:
Primeras dudas, sentencia for:
(demasiado antiguo para responder)
N0K
2004-11-17 12:55:49 UTC
Permalink
Buenas empiezo con mis primeras dudillas, este programilla lo que va
haciendo es pedir nombres y los almacena en una matriz bidimensional.
Todo va bien, pero en el primer nombre ( nombre[ 0 ] ) por defecto me
mete un retorno de carro, con lo cual pasa directamente a pedirme el
nombre[1]. He probado colocando " fflush(stdin); " en unos cuantos
sitios de la sentencia for donde creo que esta el error. Y por último,
no entiendo la forma en la que se recogen las cadenas de caracteres, "
fin = gets(nombre[fila]); " fin se ha definido antes como char *fin
eso es un puntero verdad ? (aun no he llegado a los punteros) pero no
entiendo como de esta forma se pueden guardar los datos en la matriz.

El código lo compilo en linux no se si tiene algo que ver y como
curiosidad, al compilarlo me suelta esto:

gcc cadenas.c -o cadenas.o
/tmp/ccQAKOIb.o(.text+0xcd): En la función `main':
: warning: the `gets' function is dangerous and should not be used.


Aquí va el código:

/***** Leer una lista de nombres *****/
/* cadenas.c
*/

#include <stdio.h>
#include <stdlib.h>

#define FILAS_MAX 100
#define COLS_MAX 80

main()
{
// Matriz de cadenas de caracteres
char nombre[FILAS_MAX][COLS_MAX];
int nFilas = 0;
int fila = 0;
char *fin, respuesta;

do
{
printf("Número de filas de la matriz: ");
scanf("%d", &nFilas);
}
while (nFilas < 1 || nFilas > FILAS_MAX);
fflush(stdin);

printf("Escriba los nombres que desea introducir.\n");
printf("Puede finalizar pulsando las teclas [Ctrl][d].\n");

for (fila = 0; fila < nFilas; fila++)
{
printf("Nombre[%d]: ", fila);
fin = gets(nombre[fila]);
// Si se pulsó [Ctrl][D], salir del bucle
if (fin == NULL) break;
}

nFilas = fila; // número de filas leidas
do
{
printf("¿Desea visualizar el contenido de la
matriz?(s/n): "); respuesta = tolower(getchar());
fflush(stdin);
}
while (respuesta != 's' && respuesta != 'n');

if ( respuesta == 's' )
{
// Visualizar la lista de nombres
printf("\n");
for (fila = 0; fila < nFilas; fila++)
printf("%s\n", nombre[fila]);
}
}


Muchas dudas para recien empezar no ???

Gracias y un saludo,
N0K.
Lepton
2004-11-17 18:12:50 UTC
Permalink
On Wed, 17 Nov 2004, N0K wrote:

# Buenas empiezo con mis primeras dudillas, este programilla lo que va
# haciendo es pedir nombres y los almacena en una matriz bidimensional.
# Todo va bien, pero en el primer nombre ( nombre[ 0 ] ) por defecto me
# mete un retorno de carro, con lo cual pasa directamente a pedirme el
# nombre[1]. He probado colocando " fflush(stdin); " en unos cuantos

No uses gets(), usa fgets(). No solo es mas seguro (gets() no sabe
el tamaño maximo del buffer)

Por otro lado, usa strrcr() para comprobar si hay un retorno de carro
('\r' y/o '\n') al final de la linea, y si es asi, eliminalo.

# sitios de la sentencia for donde creo que esta el error. Y por último,
# no entiendo la forma en la que se recogen las cadenas de caracteres, "
# fin = gets(nombre[fila]); " fin se ha definido antes como char *fin
# eso es un puntero verdad ? (aun no he llegado a los punteros) pero no
# entiendo como de esta forma se pueden guardar los datos en la matriz.

si nombre[fila] es un puntero a un buffer donde quieres guardar la
cadena de texto, eso es correcto. el puntero fin deberia apuntar al
primer caracter de nombre[fila] (una vez leido), o NULL si ha habido
algun error.

# El código lo compilo en linux no se si tiene algo que ver y como
# curiosidad, al compilarlo me suelta esto:
#
# gcc cadenas.c -o cadenas.o
# /tmp/ccQAKOIb.o(.text+0xcd): En la función `main':
# : warning: the `gets' function is dangerous and should not be used.

Eso es porque si haces, eg:

char buffer[10];
gets(buffer);

y el usuario escribe mas de 9 letras, gets() escribira todo sin pensar,
asi que se 'desborda' el buffer.

# Aquí va el código:
#
# /***** Leer una lista de nombres *****/
# /* cadenas.c
# */
#
# #include <stdio.h>
# #include <stdlib.h>
#
# #define FILAS_MAX 100
# #define COLS_MAX 80
#
# main()

int main(void)

# {
# // Matriz de cadenas de caracteres
# char nombre[FILAS_MAX][COLS_MAX];
# int nFilas = 0;
# int fila = 0;
# char *fin, respuesta;
#
# do
# {
# printf("Número de filas de la matriz: ");
# scanf("%d", &nFilas);

Consejo: no uses scanf(), es una de las funciones mas complejas del C,
aunque por alguna razon es la segunda que se enseña, despues de printf(),
que es incluso mas compleja :)

El problema es scanf() deja el retorno de carro ('\n') en el buffer
de teclado (stdin), asi que la proxima vez que leas de stdin, te
devolvera una linea vacia..

# }
# while (nFilas < 1 || nFilas > FILAS_MAX);
# fflush(stdin);

fflush() solo es aplicable a ficheros abiertos para escribir (como
stdout, por ejemplo).

# printf("Escriba los nombres que desea introducir.\n");
# printf("Puede finalizar pulsando las teclas [Ctrl][d].\n");
#
# for (fila = 0; fila < nFilas; fila++)
# {
# printf("Nombre[%d]: ", fila);
# fin = gets(nombre[fila]);
# // Si se pulsó [Ctrl][D], salir del bucle
# if (fin == NULL) break;
# }
#
# nFilas = fila; // número de filas leidas
# do
# {
# printf("¿Desea visualizar el contenido de la
# matriz?(s/n): "); respuesta = tolower(getchar());
# fflush(stdin);

getchar() devuelve un 'int', no un 'char' (principalmente porque
si hay error, se devuelve EOF, que suele ser (int)-1, y eso no
cabe en un char (-1 no es lo mismo que 255 para getchar())

# }
# while (respuesta != 's' && respuesta != 'n');
#
# if ( respuesta == 's' )
# {
# // Visualizar la lista de nombres
# printf("\n");
# for (fila = 0; fila < nFilas; fila++)
# printf("%s\n", nombre[fila]);
# }
# }
#
# Muchas dudas para recien empezar no ???

No, son dudas bastante comunes. Te esta enseñando alguien? o estas
apriendiendo de algun libro?

Lepton.
N0K
2004-11-17 18:56:27 UTC
Permalink
Muchas gracias, estoy siguiendo el siguiente libro "C/C++ Curso de
programación" de Fco. Javier Ceballos. El código que he puesto
pertenece a un ejemplo.
Las cosas que he utilizado (como scanf) son las que han ido
apareciendo en el libro, como bien has dicho ha sido practicamente la
2 despues de printf. Aún no puedo poner otras porque no las conozco.
Pero lo tendré en cuenta para cuando llegue a ellas.

Gracias y un saludo,
N0K.
Post by Lepton
# Buenas empiezo con mis primeras dudillas, este programilla lo que
# va haciendo es pedir nombres y los almacena en una matriz
# bidimensional. Todo va bien, pero en el primer nombre ( nombre[ 0
# ] ) por defecto me mete un retorno de carro, con lo cual pasa
# directamente a pedirme el nombre[1]. He probado colocando "
# fflush(stdin); " en unos cuantos
No uses gets(), usa fgets(). No solo es mas seguro (gets() no sabe
el tamaño maximo del buffer)
Por otro lado, usa strrcr() para comprobar si hay un retorno de
carro('\r' y/o '\n') al final de la linea, y si es asi, eliminalo.
# sitios de la sentencia for donde creo que esta el error. Y por
# último, no entiendo la forma en la que se recogen las cadenas de
# caracteres, " fin = gets(nombre[fila]); " fin se ha definido antes
# como char *fin eso es un puntero verdad ? (aun no he llegado a los
# punteros) pero no entiendo como de esta forma se pueden guardar
# los datos en la matriz.
si nombre[fila] es un puntero a un buffer donde quieres guardar la
cadena de texto, eso es correcto. el puntero fin deberia apuntar al
primer caracter de nombre[fila] (una vez leido), o NULL si ha habido
algun error.
# El código lo compilo en linux no se si tiene algo que ver y como
#
# gcc cadenas.c -o cadenas.o
# : warning: the `gets' function is dangerous and should not be
# used.
char buffer[10];
gets(buffer);
y el usuario escribe mas de 9 letras, gets() escribira todo sin
pensar, asi que se 'desborda' el buffer.
#
# /***** Leer una lista de nombres *****/
# /* cadenas.c
# */
#
# #include <stdio.h>
# #include <stdlib.h>
#
# #define FILAS_MAX 100
# #define COLS_MAX 80
#
# main()
int main(void)
# {
# // Matriz de cadenas de caracteres
# char nombre[FILAS_MAX][COLS_MAX];
# int nFilas = 0;
# int fila = 0;
# char *fin, respuesta;
#
# do
# {
# printf("Número de filas de la matriz: ");
# scanf("%d", &nFilas);
Consejo: no uses scanf(), es una de las funciones mas complejas del
C, aunque por alguna razon es la segunda que se enseña, despues de
printf(), que es incluso mas compleja :)
El problema es scanf() deja el retorno de carro ('\n') en el buffer
de teclado (stdin), asi que la proxima vez que leas de stdin, te
devolvera una linea vacia..
# }
# while (nFilas < 1 || nFilas > FILAS_MAX);
# fflush(stdin);
fflush() solo es aplicable a ficheros abiertos para escribir (como
stdout, por ejemplo).
# printf("Escriba los nombres que desea introducir.\n");
# printf("Puede finalizar pulsando las teclas
# [Ctrl][d].\n");
#
# for (fila = 0; fila < nFilas; fila++)
# {
# printf("Nombre[%d]: ", fila);
# fin = gets(nombre[fila]);
# // Si se pulsó [Ctrl][D], salir del bucle
# if (fin == NULL) break;
# }
#
# nFilas = fila; // número de filas leidas
# do
# {
# printf("¿Desea visualizar el contenido de la
# matriz?(s/n): "); respuesta = tolower(getchar());
# fflush(stdin);
getchar() devuelve un 'int', no un 'char' (principalmente porque
si hay error, se devuelve EOF, que suele ser (int)-1, y eso no
cabe en un char (-1 no es lo mismo que 255 para getchar())
# }
# while (respuesta != 's' && respuesta != 'n');
#
# if ( respuesta == 's' )
# {
# // Visualizar la lista de nombres
# printf("\n");
# for (fila = 0; fila < nFilas; fila++)
# printf("%s\n", nombre[fila]);
# }
# }
#
# Muchas dudas para recien empezar no ???
No, son dudas bastante comunes. Te esta enseñando alguien? o estas
apriendiendo de algun libro?
Lepton.
J.A. Gutierrez
2004-11-17 19:11:56 UTC
Permalink
In es.comp.lenguajes.c N0K <n0k-***@fujitsu.es> wrote:
: Muchas gracias, estoy siguiendo el siguiente libro "C/C++ Curso de
: programación" de Fco. Javier Ceballos. El código que he puesto
: pertenece a un ejemplo.

Pues si pertenece a un libro, muy mal.
fflush(stdin) es algo que no conviene dar como ejemplo
(de hecho, no conviene utilizarlo en absoluto) ya que
su comportamiento no esta definido.

http://www.eskimo.com/~scs/C-faq/q12.26.html


Ah, y procura no responder por encima del mensaje original y recortar
el texto citado a lo justo para conservar el contexto.

http://www.escomposlinux.org/grupos/consejos.php
--
PGP and other useless info at \
http://webdiis.unizar.es/~spd/ \
finger://daphne.cps.unizar.es/spd \ Timeo Danaos et dona ferentes
ftp://ivo.cps.unizar.es/pub/ \ (Virgilio)
Lepton
2004-11-17 23:45:53 UTC
Permalink
On Wed, 17 Nov 2004, N0K wrote:

# Muchas gracias, estoy siguiendo el siguiente libro "C/C++ Curso de
# programación" de Fco. Javier Ceballos. El código que he puesto
# pertenece a un ejemplo.

Como ya te han dicho, me parece muy mal que en un libro venga eso
de fflush(stdin). Por otro lado, C no es lo mismo que C++, asi que
no entiendo porque el libro intenta tratar los dos lenguajes al
mismo tiempo (en C++ no deberia usarse printf(), por ejemplo)

# Las cosas que he utilizado (como scanf) son las que han ido
# apareciendo en el libro, como bien has dicho ha sido practicamente la
# 2 despues de printf. Aún no puedo poner otras porque no las conozco.
# Pero lo tendré en cuenta para cuando llegue a ellas.

Para el futuro, cuando compres un libro de C, echale un vistazo
primero (si es posible, si no busca referencias), y si ves algo
como 'fflush(stdin)' (comportamiento no definido), o 'void main()'
(C++, pero no C), o '#include <conio.h>' (Borland), entonces no
lo compres.

Mira si ves algun libro moderno donde el titulo incluya la palabra
'ANSI', pero no 'C++' ni 'MS-DOS' ni 'UNIX' ni 'Linux' ni 'Windows':
esto es, un libro de C, ni mas ni menos :)

Lepton.
N0K
2004-11-18 19:31:48 UTC
Permalink
Post by Lepton
Mira si ves algun libro moderno donde el titulo incluya la palabra
esto es, un libro de C, ni mas ni menos :)
Alguna recomendación, ya sea libro o tutorial ???

Saludos,
N0K.
Lepton
2004-11-18 20:50:35 UTC
Permalink
On Thu, 18 Nov 2004, N0K wrote:

# > Mira si ves algun libro moderno donde el titulo incluya la palabra
# > 'ANSI', pero no 'C++' ni 'MS-DOS' ni 'UNIX' ni 'Linux' ni 'Windows':
# > esto es, un libro de C, ni mas ni menos :)
#
# Alguna recomendación, ya sea libro o tutorial ???

El mejor libro de C es "The C Programming Language ANSI C Version"
de Kernighan & Ritchie (ISBN: 0-13-110362-8)

Puedes encontrar un tutorial (que tiene mas o menos buena pinta) en:

http://www.le.ac.uk/cc/tutorials/c/

Lepton.

Loading...