Problema con C - Tengo un bucle infinito que no se ejecuta :S

Ya, ya se que esto mejor en general, pero aqui se que me podeis ayudar mejor ;)

La cuestion esque estoy intentando hacer un pequeño programa muy sencillo que mueva un caracter de un lado a otro de la pantalla, pero no se porque no se llega a ejecutar el bucle infinito que haria que estubiese todo el rato moviendose y llevo dos dias mirando el programa y soy incapaz de saber que narices le pasa :(

Os dejo el codigo:

      1 #include <unistd.h>
      2 #include <stdio.h>
      3 #define ANCHO 100
      4 #define TIEMPO 10000
      5
      6 int main(void)
      7 {
      8         int i, lim_lat=1, lateral=1;
      9         system("clear");
     10         while(1){
     11
     12                 if(lim_lat==1)//establecemos que si el lmite latrel es 1 se movera hacia la derecha
     13                 {
     14
     15                         printf("blabla");
     16                         for(i=0; i<=lateral; i++) printf(" ");//escribimos tantos espacios como veces se hallan movido las lineas
     17                         lateral++;
     18                         printf("*");
     19                         sleep(TIEMPO);
     20                         system("clear");
     21                         puts("");
     22                         if(lateral==ANCHO) lim_lat=0;//con esto invertimos el sentido del caracter
     23                 }//con esto terminamos el trozo de funcion que hace que se mueva hacia la derecha
     24
     25                 if(lim_lat==0)//con esto establecemos que si el limite lateral esta a 0 nuestro caracter se movera hacia la izquierda
     26                 {
     27                         for(i=lateral; i>=1; i--) printf(" ");
     28                         lateral--;
     29                         printf("*");
     30                         sleep(TIEMPO);
     31                         system("clear");
     32                         if(lateral==0) lim_lat=1;//con esto invertimos el sentido del caracter
     33                 }//con esto establecemos que si el limite lateral esta a 1 cambiaremos el sentido del movimiento al hacer cambiar el valor del switch
     34         }
     35         return 0;
     36 }


Tengo otro programa muy similar pero envez de un caracter es un cuadrado que se mueve hacia arriba y hacia abajo y ese si que funciona bien.

Salu2 y muchas gracias!

PD: se que el bucle no se llega a ejecutar por que nada mas empezar el bucle he probado a poner un printf y no lo saca por pantalla
Claro que se está ejecutando. Lo que pasa es que los datos no se están escribiendo a la terminal porque stdout es 'buffered'. fflush(stdout); antes de los sleep parece hacerlo funcionar.

PD: He tardado más en reidentar y poner el código legible que en encontrar el problema...

- ferdy
Pues yo veo una cosita: TIEMPO es la hostia de grande :Ð, cambiándolo símplemente por 1 el programa hace lo que explicas.

Edito: Ferdy, kwrite, herramientas, sangrado inverso [burla2]. KDE FTW.
Ferdy escribió:Claro que se está ejecutando. Lo que pasa es que los datos no se están escribiendo a la terminal porque stdout es 'buffered'. fflush(stdout); antes de los sleep parece hacerlo funcionar.


Ok, probare, muchas gracias ;)


Ferdy escribió:PD: He tardado más en reidentar y poner el código legible que en encontrar el problema...

- ferdy


Te agradeceria que me dijeses que es eso que esta mal escrito para poder mejorarlo :)

Gooler escribió:Pues yo veo una cosita: TIEMPO es la hostia de grande :Ð, cambiándolo símplemente por 1 el programa hace lo que explicas.


Te aseguro que el tiempo no es muy grande xD no se porque pero la funcion usleep me toma valores inferiores a milisegundos y la funcion sleep me los toma como segundos :S

Salu2 y gracias a los 2!
\-\adEs escribió:Te aseguro que el tiempo no es muy grande xD no se porque pero la funcion usleep me toma valores inferiores a milisegundos y la funcion sleep me los toma como segundos :S


Es que es precisamente lo que hacen:
man 3 usleep
La función usleep() suspende la ejecución del proceso llamante durante usec microsegundos.
man 3 sleep
sleep() hace que el proceso en curso se duerma hasta que hayan transcurrido segundos segundos o hasta que llegue una señal que sea tenida en cuenta.

¿Para qué es el programa? ¿Vas a hacer un KITT en ascii XD?
Gooler escribió:
Es que es precisamente lo que hacen:
man 3 usleep
La función usleep() suspende la ejecución del proceso llamante durante usec microsegundos.
man 3 sleep
sleep() hace que el proceso en curso se duerma hasta que hayan transcurrido segundos segundos o hasta que llegue una señal que sea tenida en cuenta.

¿Para qué es el programa? ¿Vas a hacer un KITT en ascii XD?


Digamos que en clase de programacion hay un pokemon que me incita ha hacer estas cosas [qmparto] (si se pasa por aqui que de la cara XD)

Simplemente es orgullo y por programar algo y pense que seria buena idea para practicar con las sentencias de control.

Salu2!
Edito: Ferdy, kwrite, herramientas, sangrado inverso smile_[burla2]. KDE FTW.


What? no. indent.

Antes de que se cargue KDE ya habría encontrado el problema...

Te agradeceria que me dijeses que es eso que esta mal escrito para poder mejorarlo smile_:)


Veamos:

1) if, for y while no son funciones. Así que 'if (blah)' se prefiere a 'if(blah)'
2) Los operadores y los operandos se separan con espacios
3) 'for(...) algo;' es feo y confunde, usa

for (...)
    algo;


(lo mismo con 'if(...) blah;')

4) Nadie usa // para los comentarios, y hasta C99 no han existido en C.

- ferdy
Muchas gracias por tus consejos Ferdy, no dudes que los pondre en practica :)

Gracias de nuevo!!
Ferdy escribió:4) Nadie usa // para los comentarios, y hasta C99 no han existido en C.


Eso es algo que nunca he entendido. ¿Que tienen de malo? Es mucho más cómodo que /* */ para comentarios de una sola linea.
A lo que ferdy se refiere, ades, son a las normas de estilo.

Normas de estilo en C

Es a lo que yo me refería en un post del otro dia cuando hablaba de programar con "fundamentos"

Salu2
A lo que ferdy se refiere, ades, son a las normas de estilo.

Normas de estilo en C

Es a lo que yo me refería en un post del otro dia cuando hablaba de programar con "fundamentos"


Si, a eso me refería, pero no entiendo por qué la gente se empeña en crear 'nuevas normas de estilo' cuando todo el mundo que usa C para algo serio, usa el estilo K&R:

The C Programming Language - ISBN 0-13-110362-8
/usr/src/linux/Documentation/CodingStyle

- ferdy
4eVaH escribió:A lo que ferdy se refiere, ades, son a las normas de estilo.

Normas de estilo en C

Es a lo que yo me refería en un post del otro dia cuando hablaba de programar con "fundamentos"

Salu2


Muchas gracias por el link 4eVaH [oki] Link leido y aprendido para proximas escrituras de programa.

Salu2!
Pssst, que no te lave el cerebro, GNU style FTW XD
Una sujerencia:

Utiliza una variable entera lo más pequeña posible (un char viene bien) que valga 1, y cuando llegue al límite de la pantalla, la multiplicas por -1, y utilizas esa variable para mover la letra de izquierda a derecha tantos pasos como valga la variable.

Lo digo porque, aparte de optimizar la aplicación - crear ifs no es bueno, y si estás empezando a programar, acostúmbrate a comerte el seso poor intentar hacer que el ordenador trabaje lo menos posible, porque si para una aplicación pequeña escribes mucho, si algún día programas algo muy grande, tendrás tu propio Gothic3...xddd - , se lee todo más clarito que tantos ifs, que siempre son más complejos a la hora de depurar.


En la terminal de linux no sé cómo se puede hacer, pero me supongo que existe alguna forma de mover un caracter por su posición - bien con la distancia desde la izquierda, bien con sus coordenadas - en vez de tener que estar añadiendo y quitando espacios.
Utiliza una variable entera lo más pequeña posible (un char viene bien) que valga 1,


No, un char no viene bien. Un char equivoca a quien lea el código. No vas a notar diferencia entre usar un char o un int, 3 bytes no van a ningún lado.

- ferdy
Gran idea Zor!!! ^_^

Salu2!
Programar en código abierto es como escribir una carta.

Tiene que entenderla aquel que recibe la carta, no el que la escribe (se sobreentiende que el que la escribe la entiende).

Si usas char, por muy pequeño que sea el código, queda menos legible... no digo que no optimices pero tampoco te pases...
Si usas char, por muy pequeño que sea el código, queda menos legible... no digo que no optimices pero tampoco te pases...


El problema es que no hay optimización real.

- ferdy
Buenas! Vengo a pediros otro favor... (lo siento por daros el coñazo de nuevo [tomaaa] )

Estube leyendo los docs que me disteis para "intentar" mejorar la identación (¿se dice así?) e intento hacer todo lo que puedo para que siga los standares.

La cosa, tengo otro pequeño programa, os pido si me hicieseis el favor que me revisaseis la identación del programa y me dijeseis los fallos que tengo (no encuanto al código, sino a la forma de escribirlo).

Os pego el código:

/*
*
* Se generan 5 numeros no repetidos mas
* 2 estrellas (no repetidas).
* Los numeros van del 1 al 50 y las
* estrellas del 1 al nueve.
*
*/

#include <stdio.h>   /* librerias in out */
#include <stdlib.h>   /* librerias estandar */
#include <time.h>   /* librerias para el control del tiempo */
#define NUM 5      /* definimos la cantidad de numeros */
#define EST 2      /* definimos la cantidad de estrellas */
#define RG_NUM 49   /* definimos el rango de los numeros, del 1 al 50 */
#define RG_EST 8   /* definimos el rango de las estrellas, del 1 al 9 */

               /* NOTA: Utilizamos en los rangos el valor menos uno, ya que
                * despues tendremos que sumarle 1 ya que empiezan desde 0
                */


/* Declaracion de los tipos de funciones */

int generarNumero(int, int, int *);
void ordenaBurbuja(int *, int);
void muestraLista(int *, int);

/* Declaracion de la funcion principal */

int main (void){
   
    int numeros[NUM],
       estrella[EST],
           sw = 0,
       i,
       k;
   
   
       srand(time(0)); /* Iniciamos el rand */
   
   /* Generamos los 5 primeros numeros */
   
       for ( i = 0 ; i < NUM ; i++ ){
       
        numeros[NUM] = generarNumero(i, RG_NUM, numeros);
      
       }
       
   ordenaBurbuja(numeros, NUM);
       
       for ( i = 0 ; i < EST ; i++ ){
   
        estrella[i] = generarNumero(i, RG_EST, estrella);
       
        }
      
   ordenaBurbuja(estrella, EST);
   
   system("clear");
   
   printf("Programa del Euromillon\n");
   
   printf("=======================\n\n");
   
   printf("Los numeros son:\t");
   muestraLista(numeros, NUM);
   printf("\nLas estrellas son:\t");
   muestraLista(estrella, EST);
   printf("\n\nPulse intro para SALIR....");
   getchar();

   system("clear");
   
   
   return 0;
   
   }


/* Declaracion de los cuerpos de las funciones */




/*
*
* generarNumero: Creara un numero en funcion de
* un rango pasado (valor).
* Como le pasamos una lista, comprobara si es el
* primer indice, y si lo es comprobara que no
* se repita ningun numero.
*
*/


int generarNumero (int indice, int valor, int *lista){
   
   int k       = 0,
       iguales = 0,
      sw      = 0;
      
   
   do{
      
      iguales = 0;
      lista[indice] = rand() % valor + 1;
      
      if  (indice){
         puts("flag");
         for( k = 0 ; k < indice ; k++ )
            if (lista[k] == lista[indice])
               iguales = 1;
         }

      }while (iguales);
   
   return lista[indice];
      
   }
   
/*
*
* ordenaBurbuja: El algoritmo de ordenacion
* por burbuja implementado en esta funcion.
* Ordenara haciendo "subir" como las burbujas
* los valores que posea una lista.
*
*/


void ordenaBurbuja(int *la, int diml) {

     long pasadas, k;
     int  aux;       
     int  cambio;     
 
     pasadas = 1;
     cambio  = 1;

     while (cambio && pasadas <= diml-1)
     {  cambio  = 0;
        for (k = 0; k <= diml-1 - pasadas; k++)
           if (la[k] > la[k+1]){
            aux     = la[k];
            la[k]   = la[k+1];
            la[k+1] = aux;
                cambio  = 1;
              }
        pasadas++;
     }
}


/*
*
* muestraLista: Funcion que mostrara
* los valores de una lista que se ha
* pasado a la funcion como argumento.
*
*/


void muestraLista(int *lista, int i){
   
   int j;
   
   for ( j = 0 ; j < i ; j++ )
   
      printf("%d\t", lista[j]);
      
   }


Tengo algunas duda que os agradecería mucho que me las contestaseís. Son:

Las funciones, ¿se debe separar el nombre de la función de la apertura de los parentesis?

La otra es sobre los comentarios. ¿Es correcto introducir un comentario en medio de una orden, como dentro de un for? (por ejemplo for ( i = x /* comentario */ ; .... ; ... ) )

Muchas gracias por perder el tiempo corrigiendo mis fallos [tomaaa]

Salu2 y gracias!
int generarNumero(int, int, int *);
void ordenaBurbuja(int *, int);
void muestraLista(int *, int);


EnCNoLlaMamosALasFuncionesAsi si no que las_llamamos_asi

int main (void){


main es de tipo int main(int argc, char *argv[]) las llaves de las funciones van en una línea aparte.

   
    int numeros[NUM],
       estrella[EST],
           sw = 0,
       i,
       k;


Si quiero ver el tipo de 'k' tengo que ir 4 o 5 líneas más arriba, eso es malo. No pasa nada por poner el tipo en todas las lineas.

srand(time(0)); /* Iniciamos el rand */


No comentes lo que hace el código, eso debe ser obvio al leerlo, comenta (si es necesario) el por qué.

for ( i = 0 ; i < NUM ; i++ ){


Mejor así:

for (i = 0; i < NUM; i++) {


numeros[NUM] = generarNumero(i, RG_NUM, numeros);


Intuyo que quieres decir numeros[i] y no numeros[NUM]. Cuando los bucles solo tienen una instrucción, se omiten las llaves.

int generarNumero (int indice, int valor, int *lista){


Lo mismo con la llave y los tipos de k iguales y sw.

   do{


La llave se separa del 'do' con un espacio.

lista[indice] = rand() % valor + 1;


Unos paréntesis ahí no molestarían, quizá incluso ayuden.

      if  (indice){
         puts("flag");
         for( k = 0 ; k < indice ; k++ )
            if (lista[k] == lista[indice])
               iguales = 1;
         }

      }while (iguales);


La llave que cierra el if está mal puesta, debería ir a la altura del if y no del for. Deja espacios alrededor de las llaves siempre. Las llaves que cierran las funciones tambien están mal, deben tener nivel de identación = 0;

pasadas = 1;
cambio  = 1;


Dales el valor cuando las declaras.

     while (cambio && pasadas <= diml-1)
     {  cambio  = 0;


No sé qué has intentado hacer ahí, las llaves de los while van en la misma línea y la siguiente instrucción va en la siguiente línea con un nivel de identación más. Separa siempre los operadores de los operandos con un espacio, es decir, escribe diml - 1 en lugar de diml-1.

Las funciones, ¿se debe separar el nombre de la función de la apertura de los parentesis?


No.

La otra es sobre los comentarios. ¿Es correcto introducir un comentario en medio de una orden, como dentro de un for? (por ejemplo for ( i = x /* comentario */ ; .... ; ... ) )


Por poder.... se puede.... pero yo mataría si viera un código lleno de esos.

- ferdy
Tampoco te comas mucho la cabeza con el estilo en cosas como si ésta llave va en la misma línea o en la siguiente. Simplemente sé coherente con el estilo que utilices.
Por ejemplo:
Ferdy escribió:Cuando los bucles solo tienen una instrucción, se omiten las llaves.

Yo prefiero usar llaves siempre, porque me evita que me las pueda olvidar si más adelante añado otra instrucción. (A no ser que te lo estés midiendo :P)

Lo que si debes respetar es la indentación (que no identación), en alguno de los for no lo has hecho.

Un saludo.
Bueno, lo primero muchisimas gracias a los dos por molestaros en hecharle un vistazo [oki]

Lo primero que:

Ferdy escribió:Intuyo que quieres decir numeros[i] y no numeros[NUM].


Efectivamente, que el programa me funcionaba de puro milagro (por que era un puntero), pero que vamos, es un error de los muy tontos [+risas]

Otra, la funcion ordenaBurbuja no la he escrito yo, es parte de un ejemplo de mi profesora (la verdad que a veces leer el codigo que escribe la mujer es algo agobiante, apenas tiene espacios y algunas cosas qudan mas que dudosas).

Muchas gracias a los 2 (me acordare de poner todos los for iguales bastian [sonrisa] ). Seguire intentando que mi código sea mas legible :)

Salu2!
En el tema de la indentación, tú pásale el indent (sin opciones :P) a ese programa, y te lo dejará como los chorros del oro. Simplemente tendrás que eliminar algunas líneas en blanco que te sobran.
Narf escribió:En el tema de la indentación, tú pásale el indent (sin opciones :P) a ese programa, y te lo dejará como los chorros del oro. Simplemente tendrás que eliminar algunas líneas en blanco que te sobran.


Qué buena! Habia visto programas de indentacion (bueno, mas bien funciones de algunos IDE's) pero tampoco me habian gustado mucho. Voy a hecharle un vistazo al man jeje.

Salu2 y gracias!
En el tema de la indentación, tú pásale el indent (sin opciones :P) a ese programa, y te lo dejará como los chorros del oro. Simplemente tendrás que eliminar algunas líneas en blanco que te sobran.


Sin optiones te lo pone en el estilo infame ese de GNU.... es decir te destroza el código :P

- ferdy
Ferdy escribió:
Sin optiones te lo pone en el estilo infame ese de GNU.... es decir te destroza el código :P

- ferdy

El K&R sí que debería estar prohibido. ¿Llaves escondidas al final de las líneas? Ugh. Y si lo unimos a los tabs de 8 espacios de la KNF lo rematamos :P

GCC tendría que negase a compilar código que no esté en estilo GNU XD. O al menos estilo Allman, que es algo más pasable que K&R.
¡ COMO OSAS DUDAR DEL ESTILO DE NUESTROS PROFETAS K&R !
Vuestros 2 anteriores post son para guardar [qmparto] Cuando soltais de esas me dejais por los suelos XD

Salu2!
Ferdy escribió:¡ COMO OSAS DUDAR DEL ESTILO DE NUESTROS PROFETAS K&R !

¡Y tú del estilo en el que están programados tanto el compilador como la librería estándar C que estás utilizando! Eso sí tiene pecado XD
¡Y tú del estilo en el que están programados tanto el compilador como la librería estándar C que estás utilizando!


Ppffff ¿ estás comparando a los creadores con los usuarios ? :P

- ferdy
Exacto: developers de gcc y glibc, creadores; tú, usuario XD

Bien, ya hemos flameado emacs/vi, fvwm/fluxbox, mrxvt/aterm y gnu/k&r. ¿Nos queda alguno? XD
Sin duda nos falta la mayor (y en la que se montaria una gorda....):

GENTOO vs DEBIAN :P a ver quien se atreve con eso :P

Salu2!
Nah, en esas cosas Ferdy y yo estamos más o menos de acuerdo XD
Exacto: developers de gcc y glibc, creadores; tú, usuario


Meeeeeeeeeeeeeek error. K&R creadores del lenguaje, desarrolladores de GNU, meros usuarios de lo que crearon nuestros profetas.

- ferdy
34 respuestas