[C con Clase] Problema al leer datos de un documento externo al programa

Steven Davidson srd4121 en njit.edu
Lun Abr 16 23:15:49 CEST 2012


Hola Marcos,

On 4/16/2012 4:43 PM, Marcos Collado Martín wrote:
> Muchas gracias Steven, ya he lo he conseguido :), ahora me ha surgido
> otra duda, tengo que hacer una id de producto aleatoria con una
> letra y dos numeros.
> Ej: B12
> El caso que lo he estado intentando, y bueno te dejo el codigo que
> creo que se explicara mejor que yo:
>
> http://paste2.org/p/1982279
>
> En ese codigo lo que hago es a la letra darle un valor en ASCII, pero
> luego como lo paso a caracter?
>

En C/C++, no hay diferencia entre caracteres y sus códigos ASCII, por lo 
que no hay conversión necesaria.

En tu código, escribes:

srand( time(0) );
letra = 65 + rand() % (90 - 65);

que se puede escribir como,

letra = 'A' + rand() % ('Z'-'A');

Creo que esto se entiende mejor que usando sus códigos ASCII, que te 
puedo asegurar que nadie los ha memorizado todos; ni falta que hace.


Luego escribes,

srand( time(0) );
num = 10 + rand() % 90;

El problema es que invocas 'srand()' más de una vez en tu programa, lo 
cual es incorrecto. Esta función sólo debería invocarse UNA vez en tu 
programa. De lo contrario, seguramente acabarás por tener unos 
resultados menos aleatorios de lo esperado.


Como indicas en tu comentario del código fuente, el problema yace en 
esta invocación:

printf( "%i%i\n", letra, num );

Usas el especificador %i para mostrar una letra (un carácter), en lugar 
de %c, por lo que mostrará el código ASCII que es tal letra. Deberías 
escribir,

printf( "%c%i\n", letra, num );

Sinceramente, sugiero usar 'cout' ya que toma en cuenta el tipo de cada 
parámetro en lugar de tener que indicarlo tú mismo. Esto en C++, sería,

cout << letra << num << endl;


Quiero señalar un matiz sobre la implementación. Como vas a usar el 
resultado como un código para representar la identificación de un 
producto, sugiero que trates la información como una cadena de 
caracteres. Así no tienes que andar cambiando de caracteres a enteros y 
además puedes aceptar códigos con este formato: "L0d", es decir una 
letra seguida de un número de un solo dígito precedido del dígito, 0 
(cero). Esto sería sencillamente,

srand( time(NULL) );

char szIDProducto[4];
szIDProducto[0] = 'A' + rand() % 26;  // Hay 26 letras en inglés
szIDProducto[1] = '0' + rand() % 10;  // Hay 10 dígitos
szIDProducto[2] = '0' + rand() % 10;
szIDProducto[3] = 0;  // Carácter nulo indica el final de la cadena


Por cierto, el cálculo que usamos para controlar el intervalo de valores 
generados pseudo-aleatoriamente no es el "más correcto". Es un cálculo 
fácil y rápido de hacer, pero no necesariamente el mejor. Tendríamos que 
realizar un cambio de escala y posiblemente de desplazamiento, lo cual 
ya hemos hecho. El cálculo "correcto" sería el siguiente,

valor = valor_inicial + (int)( nCantidad * (rand() / (RAND_MAX+1.0)) + 0.5);

donde 'nCantidad' es la cantidad de números en el intervalo que 
queremos; es decir,

nCantidad = valor_final - valor_inicial;


Espero que todo esto te ayude.

Steven





Más información sobre la lista de distribución Cconclase