Hola a todos y que tengan un muy buen dia.
Lenguaje......................: "C"
Sistema operativo......: Windows XP
Compilador..................: MinGW
Problema.....................: No puedo concluir el programa porque no logro mover
asía la izquierda los dígitos restantes e insertar el '\0'.-
Error..............................: Ninguno.
Otras Observaciones: Para todo aquellos que tengan mucho tiempo, me
podrían indicar que debo cambiar para obtimizarlo .
Código..........................:
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
int verifica(char ingreso[], int ok, int longitud, int maxDescartar);
int main(){
unsigned int descartar=0, numeroFinal=0, i=0, ok=0, longitud=11;
char digitos[12] = {'\0'}, cualDescartar[2] = {'\0'};
printf("\n ---------- Programa que descompone un numero entero sin signo ----------");
do{
ok=0;
printf("\n\n Ingrece un numero entero sin signo [minimo 100 maximo %u].........: ", UINT_MAX);
fgets(digitos, longitud, stdin);
ok = verifica(digitos, ok, longitud, i);
}while(ok);
printf("\n\n");
for(; digitos[i] != NULL; i++){
printf(" [%d] = %c \n", i, digitos[i]);
}
do{
longitud=2;
ok=0;
printf("\n\n Indique con un entero sin signo del [0] al [%d] que numero desea descartar..: ", i-1);
fgets(cualDescartar, longitud, stdin);
ok = verifica(cualDescartar, ok, longitud, i);
}while(ok);
descartar = atoi(cualDescartar);
//En este lugar va lo que me falta...
printf("\n\n");
return 0;
}
int verifica(char ingreso[], int ok, int longitud, int maxDescartar){
long long temp=0, auxiliar=0;
int ch=0, i=0, ingresoInt=0;
char *p=NULL;
if((p=strchr(ingreso, '\n'))){
*p='\0';
}
else{
ingreso[longitud] = '\0';
while((ch = getchar()) !='\n' && ch!=EOF);
}
for(; ingreso[i] != NULL; i++){
if(ingreso[i] <= 47 || ingreso[i] >= 58){
ok=1;
return ok;
}
}
if(longitud == 11){
for(i=0; ingreso[i] != NULL; i++){
auxiliar = ingreso[i] - 48;
temp=10*temp+auxiliar;
}
if(temp <= 99 || temp > UINT_MAX){
ok=1;
return ok;
}
}
else{
ingresoInt = atoi(ingreso);
if(ingresoInt > maxDescartar){
ok=1;
return ok;
}
}
return ok;
}
/*
sprintf(digitos, "%d", 56789);
*/
Saludos y muchas pero muchas gracias por el tiempo dedicado a este tema.-
Daniel
Tienes que desplazar los caracteres desde "descartar"+1 a strlen(digitos) una posición hacia la izquierda y con eso has eliminado el carácter deseado.
La forma de hacerlo... un while, un for... como más te guste.
Hola a todos y que tengan un muy buen día.-
Muchas gracias eferion por la orientación, ahora el caso es que funciona pero me queda una duda que me ha hecho practicar todo un día y tuve que hacer algo muy rebuscado porque de lo contrario me desaparecía el contenido de la variable digitos, si lo desean pueden correrlo sin la variable _digitos y con ella para ver lo que pasa, por favor si alguien encuentra el porqué le agradecería me lo diga para no dar esto por terminado y desconocer el error.-
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
int verifica(char ingreso[], int ok, int longitud, int maxDescartar);
int main(){
unsigned int descartar=0, numeroFinal=0, i=0, ok=0, longitud=11;
char digitos[12] = {'\0'}, _digitos[12] = {'\0'}, cualDescartar[2] = {'\0'};
printf("\n ---------- Programa que descompone un numero entero sin signo ----------");
do{
ok=0;
printf("\n\n Ingrece un numero entero sin signo [minimo 100 maximo %u].........: ", UINT_MAX);
fgets(digitos, longitud, stdin);
ok = verifica(digitos, ok, longitud, i);
}while(ok);
printf("\n\n");
for(; digitos[i] != NULL; i++){
printf(" [%d] = %c \n", i, digitos[i]);
}
do{
longitud=2;
ok=0;
printf("\n\n Indique con un entero sin signo del [0] al [%d] que numero desea descartar..: ", i-1);
fgets(cualDescartar, longitud, stdin);
ok = verifica(cualDescartar, ok, longitud, i);
}while(ok);
descartar = atoi(cualDescartar);
for(i=descartar; digitos[i] != NULL; i++){
digitos[i] = digitos[i+1];
}
numeroFinal = atoi(digitos);
printf("\n\n El numero final es = %d", numeroFinal);
printf("\n\n");
return 0;
}
int verifica(char ingreso[], int ok, int longitud, int maxDescartar){
long long temp=0, auxiliar=0;
int ch=0, i=0, ingresoInt=0;
char *p=NULL;
if((p=strchr(ingreso, '\n'))){
*p='\0';
}
else{
ingreso[longitud] = '\0';
while((ch = getchar()) !='\n' && ch!=EOF);
}
for(; ingreso[i] != NULL; i++){
if(ingreso[i] <= 47 || ingreso[i] >= 58){
ok=1;
return ok;
}
}
if(longitud == 11){
for(i=0; ingreso[i] != NULL; i++){
auxiliar = ingreso[i] - 48;
temp=10*temp+auxiliar;
}
if(temp <= 99 || temp > UINT_MAX){
ok=1;
return ok;
}
}
else{
ingresoInt = atoi(ingreso);
if(ingresoInt > maxDescartar){
ok=1;
return ok;
}
}
return ok;
}
Saludos.
Daniel
Efectivamente, tal como lo tenias se "perdía" exactamente el digito[0]. Eso es algo que comprobé tanto en el Code::Blocks como en el DeV-C++ y sospecho que es un bug del compilador ya que también lo probé en el programa PellesC que usa otro compilador y en éste último el programa no perdía al mencionado dígito, funcionaba correctamente.
Otra forma de que te funcione sin añadir _digitos es intercambiando los char, así:char cualDescartar[2] = {'\0'},digitos[12] = {'\0'} ;
Lo probé de mil y una manera pero tal como lo tenias no había forma, se pierde el primer dígito, así que tranquilo, no te pasa a ti sólo. A ver si algún maestro se digna mirarlo.
Por si acaso eso ocurre le facilito el código donde se imprime digito[0]antes, que está O.K, y después, donde "desaparece":#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <string.h>
int verifica(char ingreso[], int ok, int longitud, int maxDescartar);
int main(){
unsigned int descartar=0, i=0, ok=0, longitud=11;
char digitos[12], cualDescartar[2] ;
printf("\n ---------- Programa que descompone un numero entero sin signo ----------");
do{
ok=0;
printf("\n\n Ingrece un numero entero sin signo [minimo 100 maximo %u].........: ", UINT_MAX);
fgets(digitos, longitud, stdin);
ok = verifica(digitos, ok, longitud, i);
}while(ok);
printf("\n\n");
for(i=0; digitos[i]; i++){
printf(" [%d] = %c \n", i, digitos[i]);
}
digitos[i]='\0';
printf("\n [0] = %c \n", digitos[0]);/* <==AQUI SI ESTA */
do{
longitud=2;
ok=0;
printf("\n\n Indique con un entero sin signo del [0] al [%d] que numero desea descartar..: ", i-1);
fgets(cualDescartar, longitud, stdin);
ok = verifica(cualDescartar, ok, longitud, i);
}while(ok);
printf("\n [0] = %c \n", digitos[0]); /* <==AQUI DESAPARECE ...... */
descartar = atoi(cualDescartar);
printf(" descartar = %d \n", descartar);
system("pause");
//En este lugar va lo que me falta...
for (i=descartar;digitos[i] ;i++){ /* <==IMPRIME BIEN PORQUE NO EMPIEZA EN CERO */
digitos[i]=digitos[i+1];
printf(" [%d] = %c \n", i, digitos[i]);
}
for (i=0;digitos[i];i++){
printf(" [%d] = %c \n", i, digitos[i]);/* <==NO IMPRIME PORQUE EMPIEZA EN CERO */
}
printf("\n\n");
return 0;
}
int verifica(char ingreso[], int ok, int longitud, int maxDescartar){
long long temp=0, auxiliar=0;
int ch=0, i=0, ingresoInt=0;
char *p=NULL;
if((p=strchr(ingreso, '\n'))){
*p='\0';
}
else{
ingreso[longitud] = '\0';
while((ch = getchar()) !='\n' && ch!=EOF);
}
for(i=0; ingreso[i] ; i++){
if(ingreso[i] <= 47 || ingreso[i] >= 58){
ok=1;
return ok;
}
}
if(longitud == 11){
for(i=0; ingreso[i] ; i++){
auxiliar = ingreso[i] - 48;
temp=10*temp+auxiliar;
}
if(temp <= 99 || temp > UINT_MAX){
ok=1;
return ok;
}
}
else{
ingresoInt = atoi(ingreso);
if(ingresoInt > maxDescartar){
ok=1;
return ok;
}
}
return ok;
}
¡¡¡¡ Saluditos! ..... !!!!
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)
EDITO: Sin intercambiar los char, sólo con declarar cualDescartar con dimensión mayor de 2 funciona :o char digitos[12] = {'\0'}, cualDescartar[3];
Es como si al hacer uso de la función "verifica" un elemento de la variable "cualDescartar" sobreescribiera a digitos[0] .
¿Qué decíis que "desaparece"?
Estuve probando con varios números, y no veo ninguna pérdida.
Hola leo.-
Dios mío vaya alegrón al ser vos uno de los que me ayuda, en cuanto al caso en si no puedo creer que esto pase, no parece tener ninguna lógica.-
Saludos.
Daniel
Cita de: ivancea96 en 1 Abril 2014, 19:55 PM
¿Qué decíis que "desaparece"?
Estuve probando con varios números, y no veo ninguna pérdida.
Usa mi código, que es casi como el original y debería de salirte:
---------- Programa que descompone un numero entero sin signo ----------
Ingrece un numero entero sin signo [minimo 100 maximo 4294967295].........: 123456
[0] = 1
[1] = 2
[2] = 3
[3] = 4
[4] = 5
[5] = 6
[0] = 1 <== AQUI SALE O.K
Indique con un entero sin signo del [0] al [5] que numero desea descartar..: 2
[0] = <== FIJATE AQUI, DESAPARECE EL VALOR QUE TENIA
descartar = 2
Presione una tecla para continuar . . .
Y si te funciona bien es que usas otro compilador diferente del min o NOB2014 y yo estamos embrujados. :laugh: :laugh: :laugh:¡¡¡¡ Saluditos! ..... !!!!
(http://st.forocoches.com/foro/images/smilies/aaaaa.gif)
EDITO: Creo saber ya la causa. Al declarar cualDescartar[2] con dimensión 2 y usar fgets para captarlo, un primer caracter es el digito, un segundo caracter es el nulo de fin de cadena y "un tercer" caracter es el '\n' que introduce fgets, con lo que se sobreescribe más allça de la dimensión 2 que estaba establecida y da la casualidad de que sobreescribe el primer caracter de la variable digito, por eso el problema se solventa con cualDescartar[3].
Ahora me quedo más tranquilo.Ahora me quedo más tranquilo,
Hola Ivancea99.-
Bueno no tengo nada para agregar es tal cual como dice leo, me pasa exactamente lo mismo.
CitarEDITO: Sin intercambiar los char, sólo con declarar cualDescartar con dimensión mayor de 2 funciona
Me gustó, funciona correctamente de esta manera, espero que a alguien más le pase lo mismo para que entre todos encontremos la explicación.-
Saludos.
Daniel
char digitos[12], cualDescartar[2];
// ...
do
{
longitud=2;
// ...
ok = verifica(cualDescartar, ok, longitud, i);
}while(ok);
// ...
if((p=strchr(ingreso, '\n'))){
*p='\0';
}
else{
ingreso[longitud] = '\0'; // <=========== AQUI!!!!!!
while((ch = getchar()) !='\n' && ch!=EOF);
}
por pasos:
* "cualDescartar" tiene longitud 2 ( posiciones 0 y 1 )
* "longitud" se incializa a valor 2 ( mal vamos )
* ingreso[ longitud ] = '\0' ( toma castaña, escribimos fuera del array ).
El caso es que el compilador está poniendo en la pila primero a "cualDescartar" y despues "digitos", al salirte de "cualDescartar" escribes en "digitos"
Vaya, leosansan hemos puesto la respuesta a la vez XDDDD
Hola a todos.
Citarfgets - Leerá hasta n-1 caracteres o hasta que lea un retorno de línea (\n).
En este último caso , el carácter de retorno de línea también es leído.-
unsigned int descartar=0, numeroFinal=0, i=0, ok=0, longitud=11;
char digitos[12] = {'\0'}, cualDescartar[3] = {'\0'};
fgets(digitos, longitud, stdin);
Para dejarlo en mi caso del todo claro, ¿esta es la manera correcta de declarar el array y fgets(longitud) para capturar un máximo de 10 dígitos?
Saludos.
Daniel
"digitos" puede tener tamaño 11 perfectamente, con eso podrá almacenar una cadena de 10 caracteres.
Si quieres que el buffer sea capaz de almacenar una cadena de longitud X has de declararlo, al menos, de tamaño X+1, ya que debes reservar un espacio para el carácter nulo.
Esto solo es aplicable a cadenas de caracteres.