[AYUDA] Soy nuevo en C y tengo un problema con un codigo de 12 lineas simple

Iniciado por Noxware, 30 Octubre 2014, 01:51 AM

0 Miembros y 2 Visitantes están viendo este tema.

Noxware

Hola, recién empece a aprender C hace poco y estaba probando unas cosas y encontré un error muy irracional que no comprendo porque es.

Para empezar el código es el siguiente:
#include <stdio.h>

void main(){
        char temp[10];
        int a = 5;
       
        while(a == a){
            printf(">>> ");
            scanf("%s", &temp);
           
        }       
    }


esto desplega una consola que no hace paracticamente nada y que se ve asi:
>>>

si yo escribo una sola palabra no hay ningun problema:

>>> palabra1
y la consola queda:
>>>

Pero si le ingreso mas de una palabra, por ejemplo si le ingreso 4 palabras:
>>> palabra1 palabra2 palabra3 palabra4
la consola me queda:
>>> >>> >>> >>>

Porque sucede esto???
"La mejor forma de conocer a una persona es viendo su código... o en una partida de ajedrez...

PD: Si no tengo faltas de ortografía es porque use el autocorrector."

engel lex

le estás diciendo al scanf que lea caracteres, el scanf no asume el espacio un caracter, así que el lee lo que hay antes del primer espacio, lo saca del buffer y termina, entonces se repite tu funcion, pero ahora tienes un buffer cargado, así que el repite la operacion por cada espacio... esto es util cuando vas a sacar datos diferentes como
hola 1 2.30

puedes sacar hola como string, 1 como int y 2.3 como float :P

si no quieres que suceda ese error debes limpiar el buffer
esta es una linea que sirve para eso
while ( getchar() != '\n' );
lo que hace es leer hasta que consigue el enter

tambien
fseek(stdin,0,SEEK_END);
que usa la busqueda para en el buffer de entrada (stdin) pararse al final


ese es el asunto con C que es de más bajo nivel que casi todos los comunes y al programador le toca hacer las verificaciones que se asumen obvias pero esos huecos son los que dan real control
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Noxware

Y como hago para que leea todo el string??? osea si quisiera imprimir todo lo que ingrese como lo haria???? porque al hacerlo asi solo me va a cargar la primera palabra pero no el resto....
"La mejor forma de conocer a una persona es viendo su código... o en una partida de ajedrez...

PD: Si no tengo faltas de ortografía es porque use el autocorrector."

engel lex

puedes empezar con c++ que te hace más facil mucho del trabajo...
#include <stdio.h>

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;
int main(){
       char temp[10];
       int a = 5;

       while(a == a){
           cout << ">>> ";
           cin >> temp;
       }        
        return 0;
}



o si quieres hacerlo en c puedes hacer esto

fgets(temp, 10, stdin); //capturas 10 caracteres del buffer de entrada
strtok(temp, "\n");//quita el salto de linea



por cierto... cuidado con otras cosas como intentar comparar cadenas de variables, ya que si haces

a==b
y son char de 10... recuerda que nunca dejan de ser de 10 y el resto que no escribiste contiene "basura" así que no serán iguales
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Noxware

El código en C++ que me pasaste me da el mismo problema que tuve al inicio :(
"La mejor forma de conocer a una persona es viendo su código... o en una partida de ajedrez...

PD: Si no tengo faltas de ortografía es porque use el autocorrector."

engel lex

ya! XD cierto que cin tambien lo hace, pero con cin es más simple igual y tambien había olvidado el salto de linea

Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;
int main(){
   char temp[10];
   int a = 5;

   while(a == a){
       cout << ">>> ";
       cin.getline(temp,10);
       cout << endl;//salto de linea
   }        
   return 0;
}

El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

leosansan

Cita de: francoyo1998 en 30 Octubre 2014, 02:15 AM
Y como hago para que leea todo el string??? osea si quisiera imprimir todo lo que ingrese como lo haria???? porque al hacerlo asi solo me va a cargar la primera palabra pero no el resto....

* Si quisieras seguir usando scanf para captar la cadena con espacios usarías:

Código (cpp) [Seleccionar]
scanf("%[^\n]s", temp) ;

* No hace falta el uso de una variable como "a" y hacer luego "a==a" para procvocar un bucle infinito. Más breve sería usar:

Código (cpp) [Seleccionar]
while ( 1 )

* Ten en cuenta que "temp" es un array por lo que sobra "& en el scanf.

* La función "main" es de tipo "int" por lo que requiere a su vez un return de entero.

Vamos que podría ser algo como:

Código (cpp) [Seleccionar]
#include <stdio.h>

int  main ( void ) {
  char temp [100] ;
  while ( 1 ) {
   printf ( ">>> " ) ;
   scanf("%[^\n]s", temp) ;
   printf( "%s\n" , temp ) ;           
   while ( getchar() != '\n' ) ;
  }
  return 0 ;}


¡¡¡¡ Saluditos! ..... !!!!



engel lex

leosansan yo intenté eso pero me dice que ^\n no fue reconocido :s por eso ni lo intenté
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

_Enko

Soy realmente innepto en Cpp/C pero....

No seria:

Código (cpp) [Seleccionar]

#include <stdio.h>
#include <windows.h>
#include <string.h>

int  main ( void ) {
char temp [100] ;
  do {
  printf ( ">>> " ) ;
  scanf("%[^\n]s", temp) ;
  printf( "%s\n" , temp ) ;          
  }while ( (getchar() != '\n')  ||  (strcmp(temp, "END")!= 0) ) ;
system("PAUSE");
return 0 ;
}


Digo mas que nada porque el bucle infinito me parece como mala práctica.

rir3760

Algunos comentarios ...

Cita de: engel lex en 30 Octubre 2014, 02:00 AMtambien
fseek(stdin,0,SEEK_END);
que usa la busqueda para en el buffer de entrada (stdin) pararse al final
El problema con fseek es que tal vez funcione o tal vez no, mejor utilizar un bucle para descartar el resto de la linea:
{
   int ch;
   
   while ((ch = getchar()) != EOF && ch != '\n')
      ;
}

Se debe comparar contra EOF para evitar el caso donde la función getchar falla, retorna EOF y ello resulta en un bucle infinito.


Cita de: leosansan en 30 Octubre 2014, 13:37 PM
* Si quisieras seguir usando scanf para captar la cadena con espacios usarías:

scanf("%[^\n]s", temp) ;
Cuando se desea indicar un conjunto de caracteres el especificador de formato es "%[]", la 's' después de este no hace daño pero esta de mas.


Cita de: engel lex en 30 Octubre 2014, 14:37 PMleosansan yo intenté eso pero me dice que ^\n no fue reconocido :s por eso ni lo intenté
Si estas compilando el código fuente como C debería reconocerlo, es la forma de indicar que los caracteres validos son los distintos al conjunto indicado.


Cita de: _Enko en 30 Octubre 2014, 15:09 PMDigo mas que nada porque el bucle infinito me parece como mala práctica.
Depende del programa si un bucle infinito es valido o no.

Un saludo
C retains the basic philosophy that programmers know what they are doing; it only requires that they state their intentions explicitly.
--
Kernighan & Ritchie, The C programming language