Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - rir3760

#721
Cita de: m@o_614 en 22 Agosto 2013, 01:19 AMpor fin pude encontrar el error, estaba en el puntero del segundo for, cada vez que entraba de nuevo al 2do ciclo el puntero no se reiniciaba  a la primera posicion, pero ya lo pude corregir
Algunos comentarios sobre ese programa:

* Faltan los encabezados.
* Si vas a imprimir una cadena en la salida estándar y esta no termina con el carácter '\n' debes vaciar su bufer de forma explicita mediante la llamada "fflush(stdout);".
* No utilices gets, la razón de ello se explica en el tema |Lo que no hay que hacer en C/C++. Nivel basico|.
* Para terminar la función principal no es necesario llamar a la función exit, puedes utilizar la sentencia "return N;" con el mismo efecto.

Por ultimo como ya comento eferion se puede utilizar la función strchr (prototipo en <string.h>) para acortar el programa a un solo bucle. Mas o menos así:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define NUM_CHARS  7

int main(void)
{
   char num[NUM_CHARS];
   int i;
   
   printf("Dame el primer numero: ");
   fflush(stdout);
   if (fgets(num, NUM_CHARS, stdin) == NULL)
      return EXIT_FAILURE;
   
   for (i = 0; strchr("IVXLCDM", num[i]) != NULL; i++)
      ;
   if (i > 0 && (num[i] == '\n' || num[i] == '\0'))
      puts("OK");
   else
      puts("Entrada no valida");
   
   return EXIT_SUCCESS;
}

Con la limitante de indicar una entrada no valida si la linea empieza con espacio blanco.

Otra opción consiste en sustituir el bucle basado en strchr por una llamada a strspn.

Un saludo
#722
Programación C/C++ / Re: If en macros ?
20 Agosto 2013, 16:09 PM
La macros no son funciones, son sustituciones de texto y estas ocurren antes de que el texto sea compilado. Para explicarlo mejor cualquiera que haya utilizado un editor de texto (el que sea) sabe como funciona la opción para remplazar. Por ejemplo uno puede sustituir todas las instancias de la palabra "negro" por "blanco":

Texto original:
int muy_negro;
int negro;

/* ... */

negro++;

/* ... */

if (negro + negro == muy_negro)
   puts("negro, negro entonces muy negro");

/* ... */


Remplazamiento de "negro" por "blanco" resulta en:
int muy_negro;
int blanco;

/* ... */

blanco++;

/* ... */

if (blanco + blanco == muy_negro)
   puts("negro, negro entonces muy negro");

/* ... */

Este ejemplo sigue la convención de C: las sustituciones no se realizan si la palabra completa no coincide y el texto de las cadenas literales se ignora.

En el caso de las macros con argumentos se realiza la sustitución y donde se indique un argumento formal (definición de la macro) este se sustituye por el argumento actual (uso de la macro):
/* a y b son los argumentos formales */
#define SUMA(a, b) ((a) + (b))

/* ... */

int x = 1;
int y = 2;
int z;

/* ... */

/* x y y son los argumentos actuales */
z = SUMA(x, y);


Resulta en:
int x = 1;
int y = 2;
int z;

/* ... */

z = ((x) + (y));


Para darte una idea de lo que te piden si el objetivo fuera crear un macro que verifique si un carácter es alfabético en minúsculas podríamos utilizar:
#define es_minuscula(ch)  ((ch) >= 'a' && (ch) <= 'z')

/* ... */

char letra = 'j';

if (es_minuscula(letra))
   puts("Es minuscula");
else
   puts("No es minuscula");


Ya que antes de que sea compilado ese texto resulta (debido a la macro) en:
/* ... */

char letra = 'j';

if (((letra) >= 'a' && (letra) <= 'z'))
   puts("Es minuscula");
else
   puts("No es minuscula");


La macro que debes desarrollar es similar.

Un saludo
#723
Cita de: t4r0x en 12 Agosto 2013, 03:11 AMconozco los algoritmos basicos como el de burbuja , esos algoritmos estan bien y ordenan como yo quiero pero mi problema principal es que quiero saber una manera al menos un poco eficiente de saber como restaurar estas cadenas a su forma original
Lo primero que debes indicar es el lenguaje de programación que estas utilizando. Y, como ya te comentaron, los algoritmos de ordenacion solo hacen eso: ordenan.

Para realizar la operación que mencionas debes utilizar (en el caso de C) un array adicional. Este lo utilizas para almacenar los indices de (o también punteros a) cada uno de los elementos del array de valores.

Es el array de indices (o punteros) el que se ordena. Después si quieres acceder a los valores en orden accedes a ellos indirectamente mediante el array de soporte (indices o punteros).

Por ejemplo supongamos que el array de valores es:
V[0] == C
V[1] == B
V[2] == A
V[3] == E
V[4] == D


El array de indices lo inicializas con el indice del primer elemento, segundo, etc., de esta forma:
NDX[0] == 0
NDX[1] == 1
NDX[2] == 2
NDX[3] == 3
NDX[4] == 4


Y una vez ordenado el array de indices este termina así:
NDX[0] == 2
NDX[1] == 1
NDX[2] == 0
NDX[3] == 4
NDX[4] == 3

Indicando que, para imprimir en orden el array de valores, se deben imprimir los elementos con indices 2, 1, 0, 4 y 3. Un programa de ejemplo:
#include <stdio.h>
#include <stdlib.h>

int main(void)
{
   char v[5]  = {'C', 'B', 'A', 'E', 'D'};
   int ndx[5] = {0, 1, 2, 3, 4};
   int i;
   int j;
   int aux;
   
   /* Ordenacion de los indices mediante BubbleSort */
   for (i = 4; i > 0; i--)
      for (j = 0; j < i; j++)
         if (v[ndx[j]] > v[ndx[j + 1]]){
            aux = ndx[j];
            ndx[j] = ndx[j + 1];
            ndx[j + 1] = aux;
         }
   
   /* Valores segun su posicion */
   for (i = 0; i < 5; i++)
      printf("%3c", v[i]);
   putchar('\n');
   
   /* Valores segun el orden indicado por el array de indices */
   for (i = 0; i < 5; i++)
      printf("%3c", v[ndx[i]]);
   putchar('\n');
   
   return EXIT_SUCCESS;
}


Un saludo
#724
Estas compilando ese fragmento como C++, ¿Correcto?

Con la modificación que te indico avesudra debería compilar sin problemas, si no es así por favor publica el código fuente completo.

Un saludo
#725
Cita de: do-while en  8 Agosto 2013, 10:36 AM
Pues no, te pide la posición en la tabla ASCII de los caracteres y el numero de caracteres. El código queda así:
char lector[11];
char repeticiones[256];
int i,total = 0;

memset(repeticiones,0,256);

do{
  fgets(lector,10,stdin);

  for(i = 0 ; lector[i] && lector[i] != '\n' && lector[i] != '.' ; i++)
      repeticiones[lector[i]]++;

}while(!strchr(lector,'.'));

for(i = 0 ; i < 256 ; i++)
{
  if(repeticiones[i])
      printf("%c: ASCII %d\n",i,i);
  total += repeticiones[i];
}

printf("%d caracteres\n",total);
En el bucle do ... while no es necesario llamar a strchr ya que el bucle interno terminara cuando el carácter "lector[ i ]" sea igual a '\0', '\n' o '.'. Por ello basta con una comparación:
char lector[11];
char repeticiones[256] = {0};
int i,total = 0;

do {
  fgets(lector,10,stdin);

  for(i = 0 ; lector[i] && lector[i] != '\n' && lector[i] != '.' ; i++)
      repeticiones[lector[i]]++;

}while (lector[i] != '.');


Y revisando con cuidado el enunciado me parece que no es necesario imprimir la frecuencia de cada carácter, en base a ello se pueden eliminar los arrays.

Un saludo
#726
Cita de: eterno21 en  7 Agosto 2013, 14:40 PM
tengo que hacer el siguiente ejercicio:"Escribir una función que genere 6 números aleatorios entre 1 y 49, de la misma forma que en la primitiva. Obviamente, los números no pueden ser repetidos."
¿Estas aprendiendo C o C++?

Una forma fácil de generar números aleatorios no repetidos cuando el rango de estos es pequeño es simplemente seleccionar de forma aleatoria los elementos del set.

En C++ un ejemplo ya lo tienes cortesía de eferion. En C se puede implementar así:
#define SET_ELEM  49

void Primitiva(void)
{
   int set[SET_ELEM];
   int num_elem = SET_ELEM;
   
   int num[6];
   int i;
   int j;
   
   /* Valor inicial de los elementos del set */
   for (i = 0; i < SET_ELEM; i++)
      set[i] = i + 1;
   
   /* Seleccion aleatoria de seis elementos del set */
   for (i = 0; i < 6; i++){
      j = rand() % num_elem;
      num[i] = set[j];
      set[j] = set[--num_elem];
   }
   
   /* Algun proceso (por ejemplo imprimirlos) */
   for (i = 0; i < 6; i++)
      printf(" %d", num[i]);
   putchar('\n');
}


Un saludo
#727
Ya que en C y C++ los indices validos de los arrays son 0 .. N-1 otra corrección que se debe hacer a la función es cambiar la condición del bucle:
for (i = 1; i < n; i++)
   if (max < V[i]){
      max = V[i];
      pos = i;
   }


También se puede eliminar la variable "max", en su lugar para obtener el máximo basta con utilizar "V[pos]" pero si ello esta permitido depende del enunciado.

Un saludo
#728
Cita de: zonahurbana en 25 Julio 2013, 23:43 PMno entiendo mucho a qué se refiere con "dirección en memoria del objeto".
Es la definición mas cruda: un objeto es un pedazo de memoria que se interpreta de acuerdo a su tipo y si tiene nombre se le conoce como variable. La POO es tema aparte.

Cita de: zonahurbana en 25 Julio 2013, 23:43 PMAgradecería mucho que nos explique un poco más acerca de:
Código (cpp) [Seleccionar]
char (*)[12]
O tal vez pueda decirme con qué nombre más o menos buscar este tema.
Es un puntero a array, puedes buscar información sobre arrays, punteros y la relación entre ellos.

Cita de: zonahurbana en 25 Julio 2013, 23:43 PMEn este código:
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;

int main()
{
    char v[]="Probando";
    cout<<v<<endl;
    cout<<&v[0]<<endl;
    cout<<(char*)v<<endl;
    cout<<&v<<endl;
    return 0;
}

Los primeros tres argumentos que se le envían a cout son exactamente lo mismo, ¿verdad?
Correcto pero, y lo digo en buen plan, eso ya lo había explicado eferion:
Código (cpp) [Seleccionar]
&v[0] ==> &(*(v + 0)) ==> &(*(v)) ==> &*v ==> v

Cita de: zonahurbana en 25 Julio 2013, 23:43 PMLo último muestra una dirección de memoria, ¿es la de v[0]?
No. Esa es la dirección del array "v" y es de tipo "char (*)[9]" ya que al aplicar el operador "dirección de" sobre un array obtienes un puntero a ... array.

Y si realizas aritmética de punteros este (el puntero) se incrementa un numero de bytes igual al tamaño del array. Por ejemplo:
Código (cpp) [Seleccionar]
#include <iostream>
using namespace std;
 
int main()
{
   char v[] = "Probando";
   
   cout << "Direccion base: " << (void *) v << endl;
   cout << " v + 2 == " << (void *) ( v + 2) << endl;
   cout << "&v + 2 == " << (void *) (&v + 2) << endl;
   
   return 0;
}


Un saludo
#729
Cita de: zonahurbana en 24 Julio 2013, 22:58 PMEntonces podemos decir que v es como un puntero constante a char.
Cuando cout recibe un puntero a char (sea constante o no), muestra el valor apuntado por ese puntero y los valores ubicados en las direcciones de memoria que le siguen, hasta encontrar la marca de fin de cadena.

Pero al escribir &v es como querer obtener la dirección de memoria de algo que ya propiamente es una dirección de memoria y se muestra entonces la dirección de memoria de v[0]. ¿Sería la única forma de mostrar la dirección de memoria de v usando cout?

Si muestro por pantalla &p (donde p es una variable puntero que almacena la dirección de memoria de v[0]) debería pasar lo mismo (pues estoy tratando de obtener la dirección de memoria de una dirección de memoria). Pero al probar esto, la dirección que se muestra es la dirección de la variable puntero, y no se está desreferenciando una dirección de memoria, que es lo que aproximadamente sucede al hacer &v (creo que me estoy haciendo mucho lío en vano :silbar:).
Me temo que si.

El punto importante a manejar es: cuando en una expresión se refiere a un array por su nombre (o utilizando una expresión) esto resulta en la dirección en memoria del primer elemento del array, denotar un array de tipo "T [N]" resulta en un puntero de tipo "T *".

El caso usual son las cadenas de caracteres "a la C":
Código (cpp) [Seleccionar]
char a[] = "Hola, mundo";
char *p = a;

cout << a << endl;
cout << p << endl;

No hay diferencia entre las dos llamadas porque en la primera el uso de "a" genera la dirección en memoria necesaria (de a[0]).

Los dolores de cabeza se pueden generar en los casos donde esa sustitución no se da, por ejemplo cuando el operando de '&' es un array. Ese operador resulta en la dirección en memoria del objeto y si este es de tipo "T" el puntero resultante es de tipo "T *". Aquí:
Código (cpp) [Seleccionar]
char a[] = "Hola, mundo";

cout <<  a << endl; // 1)  a ==> "char *"
cout << &a << endl; // 2) &a ==> "char (*)[12]"


En el caso 1:
1) El nombre del array resulta en la dirección de su primer elemento.
2) Ya que ese puntero es de tipo "char *" el operador "<<" imprime la cadena de caracteres ahí almacenada.

En el caso 2:
1.1) Primero se procesa "&a", el nombre del array no resulta en un puntero.
1.2) La dirección resultante del operador "&" es de tipo "char (*)[12]".
2) El operando de "<<" es una dirección de memoria pero no es de tipo "char *" y por ende no se procesa como en el caso 1.

Otro caso común es el operador "sizeof".

Un saludo
#730
Este bucle:
for (p = 0; p < 61; p++){
   comodin = tiempoCaracteres[p];
   
   if (strcmp(RecvBuff,comodin) == 0){
      numero = p;
      printf("el numero del caracter es: %d", numero);
   }
}

Supongo tiene la intención de buscar cada uno de los caracteres de la cadena "tiempoCaracteres" en "RecvBuff" indicando el resultado.

Ello podría realizarse con strchr (prototipo en <string.h>) o un simple bucle pero hay problemas: para empezar no se trata de una cadena sino de una secuencia de bytes  y el numero de estos es el valor de retorno de la función recv.

Un saludo