Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: m@o_614 en 19 Diciembre 2011, 17:42 pm



Título: problema con uso de strcpy
Publicado por: m@o_614 en 19 Diciembre 2011, 17:42 pm
Código
  1.  
#include <stdio.h>
#include <stdlib.h>
//constantes//
#define IVA 16.0f
#define POR_RET_IVA 10.0f
#define POR_RET_ISR 10.0f
#define CAPTURA_MES 1
#define CAP_INGRESO 2
#define CAP_GASTOS 3
#define L_INGR_ANUALES 4
#define L_GAST_ANUALES 5
#define CALC_IMPUESTOS 6
#define SALIR 7
#define MESES 12
#define GASTOS 20
#define INGRESOS 20

void mostrar_menu();
void captura_mes();
void captura_ingreso();
void captura_gasto();
void lista_ingreso_anual();
void lista_gasto_anual();
float monto(float ganancia_bruta);
void calculo_impuestos();
void inicializa();

typedef struct registro1
{
    char concepto[30+1];
    char RFC[21+1];
    float monto;
    int mes;
    struct registro1* sig;

}ingreso;

typedef struct registro2
{
    char concepto[30+1];
    char RFC[21+1];
    float monto;
    int mes;
    struct registro2* sig;
}gasto;

//variables globales de uso interno del programa//
char *meses[MESES];
int m,contador=0,mes,reg,indice,porcentaje_ISR[3];
float rango_monto[3][2];
//arreglo de ingresos y gastos//
float gastos_meses[GASTOS],ingreso_meses[INGRESOS];

int main()
{
  //variables de programa modificables por el usuario//
  ingreso *info_registro1;
  gasto *info_registro2;

  int opcion,continuar = 1;
  inicializa();
    do
    {
        mostrar_menu();
        scanf("%d",&opcion);
        switch(opcion)
        {
            case CAPTURA_MES:
                captura_mes();
                break;
            case CAP_INGRESO:
                captura_ingreso();
                break;
            case CAP_GASTOS:
                captura_gasto();
                break;
            case L_INGR_ANUALES:
                lista_ingreso_anual();
                break;
            case L_GAST_ANUALES:
                lista_gasto_anual();
                break;
            case CALC_IMPUESTOS:
                calculo_impuestos();
                break;
            case SALIR:
                continuar = 0;
                break;
            default:printf("Opcion no valida!\n");
        }
        if(continuar){
            system("pause");
        }
    }while(continuar);
    return 0;
}

void inicializa()
{
    reg=0;
    m=0;
    mes=1;
    indice=0;
    meses[0]="Enero";
    meses[1]="Febrero";
    meses[2]="Marzo";
    meses[3]="Abril";
    meses[4]="Mayo";
    meses[5]="Junio";
    meses[6]="Julio";
    meses[7]="Agosto";
    meses[8]="Septiembre";
    meses[9]="Octubre";
    meses[10]="Noviembre";
    meses[11]="Diciembre";
    rango_monto[0][0]=0;
    rango_monto[0][1]=10000.00;
    rango_monto[1][0]=10000.00;
    rango_monto[1][1]=20000.00;
    rango_monto[2][0]=20000.00;
    rango_monto[2][1]=10000000.00;
    porcentaje_ISR[0]=11;
    porcentaje_ISR[1]=15;
    porcentaje_ISR[2]=20;
}

void mostrar_menu()
{
    ingreso*info_registro1;
    ingreso*nuevo;
    nuevo=info_registro1;
    system("cls");
    printf("CALCULO DE IMPUESTOS ANUAL\n\n");
    printf("Menu principal:\n");
    printf("1. Establecer mes para la captura (mes actual es %s)\n",meses[mes-1]);
    printf("2. Captura de ingresos\n");
    printf("3. Captura de gastos\n");
    printf("4. Mostrar lista de ingresos anual\n");
    printf("5. Mostrar lista de gastos anual\n");
    printf("6. Calculo de impuestos anual\n");
    printf("7. Salir\n");
    printf("Opcion: ");
}

void captura_mes()
{
    int indice;
    printf("Establecer mes para captura\n");
    for(contador=0,indice=0;contador<MESES;contador++,indice++)
    printf("%d) %s\n",indice+1,meses[contador]);
    printf("Elige el mes (1 a 12):\n");
    fflush(stdin);
    scanf("%d",&m);
    if(m > 12)
        printf("Mes no valido!\n");
    else
    {
        printf("Se ha establecido el mes de captura en %s\n",meses[m-1]);
        mes = m;
    }
}

void captura_ingreso()
{
    ingreso*info_registro1;
    ingreso*nuevo;
    nuevo=(ingreso*)malloc(sizeof(ingreso));
    nuevo->sig=info_registro1->sig;
    info_registro1->sig=nuevo;

    printf("Captura ingresos\n");
    printf("Dame un ingreso mas para el mes de %s: \n",meses[m-1]);
    printf("Provee datos para el ingreso %d.\n",reg);
    if(reg>INGRESOS)
       printf("no hay mas espacio\n");
    printf("RFC:");
    fflush(stdin);
    gets(nuevo->RFC);
    printf("Concepto:");
    fflush(stdin);
    gets(nuevo->concepto);
    printf("Monto:");
    fflush(stdin);
    scanf("%f",&nuevo->monto);
    nuevo->mes=m;
    ++reg;
}

void captura_gasto()
{
    gasto*info_registro2;
    gasto*nuevo;
    nuevo=(gasto*)malloc(sizeof(gasto));
    nuevo->sig=info_registro2->sig;
    info_registro2->sig=nuevo;

    printf("Captura gastos\n");
    printf("Dame el gasto del mes de %s: \n",meses[m-1]);
    printf("Provee datos para el gasto %d.\n",reg);
    if(reg>GASTOS)
       printf("no hay mas espacio\n");
    printf("Concepto:");
    fflush(stdin);
    gets(nuevo->concepto);
    printf("Monto:");
    fflush(stdin);
    scanf("%f",&nuevo->monto);
    nuevo->mes=m;
    ++reg;
}

void lista_ingreso_anual()
{
    ingreso*info_registro1;
    ingreso*nuevo;
    nuevo=info_registro1->sig;
    printf("Mostrar lista de ingresos anual\n\n");
    printf("Indice  Mes\tMonto\tRFC\t\tConcepto\n");
    printf("%d\t",indice);
    printf("%s",meses[nuevo->mes-1]);
    strcpy("nuevo->monto",ingreso_meses);
    strcpy(ingreso_meses,"nuevo->RFC");
    strcpy(ingreso_meses,"nuevo->concepto");
}

void lista_gasto_anual()
{
    gasto*info_registro2;
    gasto*nuevo;
    nuevo=info_registro2->sig;
    printf("Mostrar lista de gastos anual\n");
    printf("Indice  Mes\tMonto\tCconcepto\n");
    printf("%d\t",indice);
    printf("%s",meses[nuevo->mes-1]);
    strcpy("nuevo->monto",ingreso_meses);
    strcpy(ingreso_meses,"nuevo->concepto");
}

float monto(float gan_bruta)
{
    float por_isr;
    if((gan_bruta>rango_monto[0][0])&&(gan_bruta<=rango_monto[1][0]))
    por_isr= porcentaje_ISR[0];
    else
    if((gan_bruta>rango_monto[1][0])&&(gan_bruta<=rango_monto[2][0]))
    por_isr= porcentaje_ISR[1];
    else
    if(gan_bruta>rango_monto[2][0])
    por_isr= porcentaje_ISR[2];
    else
    por_isr=0.00;

    return(por_isr);
}

void calculo_impuestos()
{
    int contador;
    float iva,subtotal,ret_isr,ret_iva,total,gan_bruta,isr,gan_neta,isr_pag,gasto_iva,iva_pag;
    float por_isr,ingreso_total,gasto_total;

    for(contador=0;contador<=MESES;contador++)
    {
        ingreso_total=ingreso_meses[contador];
        gasto_total=gastos_meses[contador];
    }
    iva=(ingreso_total*IVA)/100;
    subtotal=ingreso_total+iva;
    ret_isr=(ingreso_total*POR_RET_ISR)/100;
    ret_iva=(ingreso_total*POR_RET_IVA)/100;
    total=subtotal-(ret_isr+ret_iva);
    gan_bruta=(ingreso_total-gasto_total);
    por_isr=monto(gan_bruta);
    isr=(gan_bruta*por_isr)/100;
    gan_neta=(gan_bruta-isr);
    isr_pag=(isr-ret_isr);
    gasto_iva=(gasto_total*IVA)/100;
    iva_pag=(iva-gasto_iva-ret_iva);
    printf("CALCULO DE IMPUESTOS\n\n");
    printf("***Tabla de Recibo de Honorarios***\n");
    printf("Ingresos\t\t%.2f\n",ingreso_total);
    printf("(+) IVA\t\t\t%.2f\n",iva);
    printf("(=) Subtotal\t\t%.2f\n",subtotal);
    printf("(-) Retención ISR\t%.2f\n",ret_isr);
    printf("(-) Retención IVA\t%.2f\n",ret_iva);
    printf("(=) Total\t\t%.2f\n",total);
    printf("***Tabla Ganancias***\n");
    printf("Ingresos\t\t%.2f\n",ingreso_total);
    printf("(-) Gastos\t\t%.2f\n",gasto_total);
    printf("(=) Ganancia Bruta\t%.2f\n",gan_bruta);
    printf("(-) ISR %.2f%%\t\t%.2f\n",por_isr,isr);
    printf("(=) Ganancia Neta\t%.2f\n",gan_neta);
    printf("***Tabla ISR***\n");
    printf("ISR %.2f%%\t\t%.2f\n",por_isr,isr);
    printf("(-) ISR Retenido\t%.2f\n",ret_isr);
    printf("(=) ISR a Pagar\t\t%.2f\n",isr_pag);
    printf("***Tabla IVA***\n");
    printf("IVA\t\t\t%.2f\n",iva);
    printf("(-) Gastos IVA\t\t%.2f\n",gasto_iva);
    printf("(-) Retención IVA\t%.2f\n",ret_iva);
    printf("(=) IVA a Pagar\t\t%.2f\n",iva_pag);
}

en este codigo me marca unos warnings en la linea 225,226 y 227, tengo problemas con el strcpy

si me pudieran ayudar con eso porfavor
gracuas


Título: Re: problema con uso de strcpy
Publicado por: naderST en 19 Diciembre 2011, 17:54 pm
El warning a lo mejor te lo tira porque la función no es segura porque puede ocurrir que trates de copiar un buffer mas grande en uno mas pequeño ocasionando lo que se conoce como un buffer overflow, para evitar esto recomiendan strncpy donde puedes tener un control de los bytes que se van a copiar.

Revisa este link: http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html (http://foro.elhacker.net/programacion_cc/lo_que_no_hay_que_hacer_en_cc_nivel_basico-t277729.0.html)

Me di cuenta en tu código que llamas a strcpy de esta manera:

Código
  1. strcpy("nuevo->monto",ingreso_meses);

Eso debería hacer que tu programa reviente porque estás tratando de modificar un literal. El prototipo de la función strcpy es el siguiente:

Código
  1. char * strcpy ( char * destination, const char * source );

Asumo que trataste de hacer lo siguiente:
Código
  1. strcpy(nuevo->monto,ingreso_meses);


Título: Re: problema con uso de strcpy
Publicado por: m@o_614 en 19 Diciembre 2011, 18:37 pm
gracias :)