Creando “vacunas” con C/C++

diciembre 2, 2010 at 1:02 am (Cpp, Programación)

Últimamente cada vez abundan más los gusanos que se propagan por MSN, por lo que me he decidido a escribir este manual sobre como programar vacunas específicas para este tipo de malware (aunque se puede extrapolar a otros). Mi objetivo es que haya más gente con capacidad de lanzar vacunas para estos gusanos cutres pero que se propagan como la espuma.

El lenguaje de programación que usaremos será C/C++ con el compilador Dev-C++, utilizando APIs. Si no sabéis que son preguntad a Google o a Wikipedia. Empezaré desde cero y ya adelanto que no voy a hacer un tutorial demasiado avanzado, puesto que quiero que lo entienda todo el mundo. Las APIs que use las explicaré por encima, para una mayor explicación podéis consultar en MSDN:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/functions_in_alphabetical_order.asp

Análisis del código maligno
Bien, explicaré el método más sencillo. Este consiste en utilizar una máquina virtual y con un programa llamado Regshot mirar que cambios ha realizado en el sistema tras su ejecución. No es el mejor método porque un programa bien hecho puede evitar ser registrado por programas así, pero es mucho más sencillo que el otro método (desensamblarlo) y como este manual pretende ser básico, será el método que usaremos.

Lo primero de todo será instalar un programa para crear máquinas virtuales, yo personalmente uso para eso VMWare. No voy a explicar como se crea una máquina virtual.

Una vez tenemos nuestra máquina virtual con el sistema operativo instalado (Windows) ya tan sólo hay que deshabilitar las conexiones (no queremos que se propague el malware ni que ataque a otros sitios mientras lo analizamos) y cerrar todo programa no imprescindible. Hacemos una primera foto con Regshot y luego otra después de haber ejecutado el malware. Entonces hacemos que compare y tendremos nuestra lista de cambios

Comencemos a programar
Antes que nada tenéis que tener instalado Dev-C++ o vuestro compilador si usáis otro, una vez hecho, vayamos al grano. Todo programa en C/C++ se divide en funciones, que son trozos de código a los que se puede llamar. Pueden devolver una salida o no (void). En C/C++ hay una función imprescindible que es main, aquella por la que empieza el programa cuando lo ejecutamos. Tiene la siguiente estructura:

int main()
{
...
}

La función main es la que menos utilizaremos, puesto que borraremos el gusano con funciones aparte, que llamaremos desde el main. Será necesario utilizar APIs, por lo que habrá que incluir el header (archivo de cabecera) que permite usarlas, que es windows.h. También queremos comunicarnos con el usuario, por lo que hace falta stdio.h (Standard Input/Output). También nos hará falta Tlhelp32.h y ctype.h (por la función toupper). Para incluir headers hay que poner las siguientes líneas al principio del código, antes que ninguna función:

#include <stdio.h>

#include <windows.h>

#include <Tlhelp32.h>

#include <ctype.h>

Matando procesos y eliminando archivos concretos
Para poder eliminar un archivo que se está ejecutando, es necesario matar antes su proceso. Para ello haremos una función que llamaremos KillProcess, que recibirá como entrada una cadena con el nombre del archivo al que hay que matar el proceso. Las funciones (excepto main) se declaran antes de poner el código de otra función y después de los headers incluidos.

Como salida nuestra función devolvera un entero (un número) indicando si ha tenido éxito o no. Para declarar la función habría que usar la sentencia siguiente:

int KillProcess(LPCTSTR lpfilename);
Luego también tendríamos que poner la función en sí, por lo que hasta ahora tendríamos que tener el código así:

Código
#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
...
}

int main()
{
...
}

Ahora veamos como matar el proceso de un archivo. Hay que declarar una serie de variables que usaremos:


WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;

Estas son las que necesitaremos para poder matar el proceso. No hace falta que los nombres de variable (la segunda palabra) sea la misma, estos son los que usaré yo aquí. Los tipos de variable no los podéis cambiar y tened en cuenta que C/C++ distingue mayúsculas de minúsculas.

Ahora tenemos que hacer como si fuera una foto de todos los procesos que se ejecutan, para ello usaremos la API CreateToolhelp32Snapshot, que tiene la siguiente forma:

HANDLE WINAPI CreateToolhelp32Snapshot(
__in DWORD dwFlags,
__in DWORD th32ProcessID
);

Luego recorremos los procesos con las APIs Process32First (para el primero) y Process32Next (para los siguientes). Tienen la siguiente forma:

BOOL WINAPI Process32First(
__in HANDLE hSnapshot,
__inout LPPROCESSENTRY32 lppe
);

BOOL WINAPI Process32Next(
__in HANDLE hSnapshot,
__out LPPROCESSENTRY32 lppe
);

Harán falta otras APIs:

//Cierra un handle abierto
BOOL WINAPI CloseHandle(
__in HANDLE hObject
);

//Abre un proceso
HANDLE WINAPI OpenProcess(
__in DWORD dwDesiredAccess,
__in BOOL bInheritHandle,
__in DWORD dwProcessId
);

//Devuelve el estado de finalización del proceso
BOOL WINAPI GetExitCodeProcess(
__in HANDLE hProcess,
__out LPDWORD lpExitCode
);

//Termina un proceso y sus threads
BOOL WINAPI TerminateProcess(
__in HANDLE hProcess,
__in UINT uExitCode
);

Para hacer todo esto, traducido a código hay que hacer lo siguiente:


handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); //Guardamos en nuestra variable de tipo HANDLE la "foto"
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR; //Si no es correcta la "foto" se acaba la funcion y se devuelve un error
pe32.dwSize = sizeof(PROCESSENTRY32); //Definimos la medida de nuestra estructura PROCESSENTRY32
if(!Process32First(handle, &pe32)) //Si hay un error al mirar el primer proceso
{
CloseHandle(handle); //Cierra el HANDLE que usamos
return ERROR_PROCESO; //Acaba la funcion devolviendo un error
}
int i; //Declaramos un par de variables más que hacen falta para pasar a mayusculas dos cadenas
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]); //Pasamos a mayúsculas las dos cadenas a comparar para que si no son exactamente iguales en cuanto a mayusculas o minusculas, también mate el proceso
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2)) /Mientras el proceso no coincida con el que buscamos...
{
if(!Process32Next(handle, &pe32)) //Va mirando el siguiente, acabando la funcion si hay errores
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]); //Pasa a mayusculas por lo que he dicho antes
}
/**Una vez hemos encontrado el proceso**//
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); //Abrimos el proceso
if(handle == NULL) //Si sale mal, damos error y salimos de la funcion
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else //Si no sale mal...
{
GetExitCodeProcess(handle, &exitcode); //Cogemos el exitcode del proceso y lo guardamos en nuestra variable destinada a ese cometido
TerminateProcess(handle, exitcode); //Matamos el proceso
CloseHandle(handle); //Cerramos el HANDLE que habiamos usado
return 0; //Devolvemos el valor 0, que es el que indicara que todo va bien y acaba la funcion
}

Como ya supongo que habréis supuesto, return se utiliza para terminar la función y devolver un valor. La doble barra sirve para introducir comentarios de una línea y también son comentario todo aquello entre /* y */. Además, también podéis ver que excepto el cero del final, los return devuelven cosas como ERROR_PROCESO. Esto sirve para llamar de una forma más recordable a una salida, en vez de usar un número. Para usar estos nombres, hay que definirlos antes, en la zona de los headers. Veamos todo lo que llevamos de código, incluyendo estas definiciones:


#define ERROR_LISTAR 1
#define ERROR_PROCESO 2

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int main()
{
...
}

Bueno, ahora que ya está hecha la función de matar el proceso, vayamos con la de borrar el archivo. Usaremos una función con la misma estructura, recibe como parámetro un archivo y de salida devuelve un entero. Para seguir poniendo de manifiesto mi gran originalidad, la llamaremos FileDelete. La declaración que habría que poner junto con la de la otra función, quedaría así:

int FileDelete(LPCTSTR lpfilename);
Para la función es muy sencillo, tan sólo hay que ver una API, que es DeleteFile:

BOOL WINAPI DeleteFile(
__in LPCTSTR lpFileName
);

El código de la función quedaría así:

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

Y el código total por ahora:

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

int main()
{
...
}

Realmente la función FileDelete es inútil, podríamos llamar directamente a la API, que es lo único que hace la función. Si no hago esto es porque más adelante (en próximos capítulos xD) ampliaremos esta función.

Borrando valores del registro
Este será el último apartado de este capítulo, el borrado de valores del registro, para por ejemplo borrar una entrada que pueda usar un gusano para autoejecutarse al inicio. Llamaremos a nuestra función RegKill, que será así:

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);
Devolverá un entero largo y como parámetros recibe un HKEY, que será en este caso HKEY_CLASSES_ROOT, HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE o HKEY_USERS, que son valores predefinidos; como segundo parámetro una cadena que indica la ruta de la clave donde está el valor a borrar y como tercer parámetro otra cadena que indica el nombre del valor a borrar.

Usaremos tres APIs para esta función. La primera es RegOpenKeyEx, que abre una clave del registro y tiene la siguiente forma:

LONG WINAPI RegOpenKeyEx(
__in HKEY hKey,
__in_opt LPCTSTR lpSubKey,
__reserved DWORD ulOptions,
__in REGSAM samDesired,
__out PHKEY phkResult
);

La segunda API es RegDeleteValue, que elimina un valor de una clave del registro y tiene la siguiente forma:

LONG WINAPI RegDeleteValue(
__in HKEY hKey,
__in_opt LPCTSTR lpValueName
);

La última es RegCloseKey, que cierra el handle abierto y tiene esta forma:

LONG WINAPI RegCloseKey(
__in HKEY hKey
);

El código de la función quedaría así:

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hregkey; //Definimos la variable donde guardaremos la ruta entera de la clave
long vuelta; //Definimos la variable donde guardaremos el valor a devolver
if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS) //Si consigue abrir la clave...
{
vuelta = RegDeleteValue(hregkey, lpValueName); //Borra el valor de la clave y guarda el resultado en "vuelta"
RegCloseKey(hregkey); //Cierra el handle que hemos usado
return vuelta; //Devuelve "vuelta"
}
else return ERROR_OPEN_REG; //Si no consigue abrir la clave, devuelve este error
}

Hace falta definir al inicio ERROR_OPEN_REG. Definiendo eso e incorporando el código, queda así:

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2
#define ERROR_OPEN_REG 3

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hregkey;
long vuelta;
if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS)
{
vuelta = RegDeleteValue(hregkey, lpValueName);
RegCloseKey(hregkey);
return vuelta;
}
else return ERROR_OPEN_REG;
}

int main()
{
...
}

Ahora que ya tenemos las funciones, falta ver que poner en el main. Esto variará según qué malware queramos eliminar. Imaginemos que tenemos un malware que crea el archivo siguiente:

C:\gusano.exe
Y se autoejecuta a cada inicio con la siguiente clave:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run\Soy un gusano malo y propagador
La función main deberá llamar a las tres funciones que hemos hecho: primero tendrá que matar el proceso, luego eliminar el archivo y después borrar el valor del registro. Quedaría así nuestro main de forma cutre:

int main()
{
KillProcess("gusano");
FileDelete("C:\\gusano");
RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
return 0;
}

Pero si nos hemos molestado en poner diferentes valores a las salidas es para tenerlos en cuenta, no para pasar de ellos. Hagamos un main que mire también como les va a nuestras funciones xDD:

int main()
{
long salida;

salida = KillProcess("gusano.exe");
if(salida == ERROR_LISTAR) printf("Error al listar los procesos\n");
else if((salida == ERROR_PROCESO) && (GetLastError() == ERROR_NO_MORE_FILES)) printf("El proceso no existe\n");
else if(salida == ERROR_PROCESO) printf("Error al manejar los procesos\n");
else printf("Proceso finalizado correctamente\n");

salida = FileDelete("C:\\gusano.exe");
if(salida == ERROR_FILE_NOT_FOUND) printf("Archivo no encontrado\n");
else if(salida == ERROR_ACCESS_DENIED) printf("Acceso denegado\n");
else if(salida) printf("Archivo eliminado correctamente\n");
else printf("Error al eliminar el archivo\n");

salida = RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
if(salida == ERROR_OPEN_REG) printf("Error al abrir el registro\n");
else if(salida == ERROR_SUCCESS) printf("Valor borrado del registro\n");
else printf("Error al borrar valor del registro\n");

return 0;
}

El hecho de que las contrabarras aparezcan duplicadas es porque la contrabarra se usa en C/C++ para las secuencias de escape (\n simboliza un salto de línea). Para poner una contrabarra, se ponen dos. Y el código entero sería así:

#define ERROR_LISTAR 1
#define ERROR_PROCESO 2
#define ERROR_OPEN_REG 3

#include
#include
#include
#include

int KillProcess(LPCTSTR lpfilename);
int FileDelete(LPCTSTR lpfilename);
long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName);

int KillProcess(LPCTSTR lpfilename)
{
WIN32_FIND_DATA Win32FindData;
HANDLE handle;
DWORD exitcode;
PROCESSENTRY32 pe32;
handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if(handle == INVALID_HANDLE_VALUE) return ERROR_LISTAR;
pe32.dwSize = sizeof(PROCESSENTRY32);
if(!Process32First(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
int i;
char lpfilename2[strlen(lpfilename) + 1];
strcpy(lpfilename2, lpfilename);
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
for(i = 0; lpfilename2[i] != ''; i++) lpfilename2[i] = toupper(lpfilename2[i]);
while(strcmp(pe32.szExeFile,lpfilename2))
{
if(!Process32Next(handle, &pe32))
{
CloseHandle(handle);
return ERROR_PROCESO;
}
for(i = 0; pe32.szExeFile[i] != ''; i++) pe32.szExeFile[i] = toupper(pe32.szExeFile[i]);
}
handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
if(handle == NULL)
{
CloseHandle(handle);
return ERROR_PROCESO;
}
else
{
GetExitCodeProcess(handle, &exitcode);
TerminateProcess(handle, exitcode);
CloseHandle(handle);
return 0;
}
}

int FileDelete(LPCTSTR lpfilename)
{
return DeleteFile(lpfilename);
}

long RegKill(HKEY hkey, LPCTSTR lpSubKey, LPCTSTR lpValueName)
{
HKEY hregkey;
long vuelta;
if(RegOpenKeyEx(hkey, lpSubKey, 0, KEY_ALL_ACCESS, &hregkey) == ERROR_SUCCESS)
{
vuelta = RegDeleteValue(hregkey, lpValueName);
RegCloseKey(hregkey);
return vuelta;
}
else return ERROR_OPEN_REG;
}

int main()
{
long salida;

salida = KillProcess("gusano.exe");
if(salida == ERROR_LISTAR) printf("Error al listar los procesos\n");
else if((salida == ERROR_PROCESO) && (GetLastError() == ERROR_NO_MORE_FILES)) printf("El proceso no existe\n");
else if(salida == ERROR_PROCESO) printf("Error al manejar los procesos\n");
else printf("Proceso finalizado correctamente\n");

salida = FileDelete("C:\\gusano.exe");
if(salida == ERROR_FILE_NOT_FOUND) printf("Archivo no encontrado\n");
else if(salida == ERROR_ACCESS_DENIED) printf("Acceso denegado\n");
else if(salida) printf("Archivo eliminado correctamente\n");
else printf("Error al eliminar el archivo\n");

salida = RegKill(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", "Soy un gusano malo y propagador");
if(salida == ERROR_OPEN_REG) printf("Error al abrir el registro\n");
else if(salida == ERROR_SUCCESS) printf("Valor borrado del registro\n");
else printf("Error al borrar valor del registro\n");

return 0;
}

Con esto doy por acabado este primer capítulo, escribiré el siguiente cuando el tiempo lo permita, en el que explicaré como hacer más cosas. Mañana si tengo tiempo pongo un ejercicio para que podáis practicar lo aprendido.

Como deberes os digo que en la función de matar procesos hay un fallo, que no es explotable ni nada, simplemente que algunos procesos según la entrada que demos no los matará. Esto para los que sepan más de C/C++.

Este texto puede ser publicado en cualquier sitio siempre que no se modifique y se cite al autor y la fuente.

Un saludo de Alex

Permalink Dejar un comentario

Porfin, programa desarrollado =D

octubre 18, 2009 at 10:47 am (Cpp, Programación)

Bueno, tras 15 días sin haber publicado nada y habiéndome dedicado al programa conseguí sacarlo, aquí la primera versión, solo falla en el “caso 5”, al imprimir el resultado, pero bueno, quitamos los últimos carácteres dejando solo el binario y nos sale exitosamente, aquí tenemos el código, el próximo paso será meterle interfaz gráfica =), estoy aprendiendo a manejarlo ya =D:


V1

#include <
stdlib.h>
#include <math.h>
#include <iostream>
#include <string.h>
using namespace std;

void ConvertirDecimalABinario();
void ConvertirDecimalAHexadecimal();
void ConvertirBinarioADecimal();
void ConvertirBinarioAHexadecimal();
void ConvertirHexadecimalABinario();
void ConvertirHexadecimalADecimal();
int ConvertirBinADecSimple(char binario[3]);
char ConvertirDecAHexSimple(int decimal);
char* ConvertirHexABinSimple(char hexa, char* bin);

int main()
{
int sistema;
system("clear");
cout << "Bienvenido al programa, indique que operacion desea realizar: " << endl;
cout << "1.- Pasar numero de binario a decimal" << endl;
cout << "2.- Pasar numero de binario a hexadecimal" << endl;
cout << "3.- Pasar numero de decimal a binario" << endl;
cout << "4.- Pasar numero de decimal a hexadecimal" << endl;
cout << "5.- Pasar numero de hexadecimal a binario" << endl;
cout << "6.- Pasar numero de hexadecimal a decimal" << endl; cin >> sistema;
switch(sistema)
{
case 1:
ConvertirBinarioADecimal();
break;
case 2:
ConvertirBinarioAHexadecimal();
break;
case 3:
ConvertirDecimalABinario();
break;
case 4:
ConvertirDecimalAHexadecimal();
break;
case 5:
ConvertirHexadecimalABinario();
break;
case 6:
ConvertirHexadecimalADecimal();
break;
default:
cout << "No introdujo un valor válido, retornando a menu principal" << main();
break;
}
}

void ConvertirBinarioADecimal() // CORRECTO
{
char *binario;
binario = new char[32];
int decimal = 0;
int cifras;

cout << "Indique el numero binario: "; cin >> binario;

// Conocer el nº de dígitos de la cifra tecleada

if(strchr(binario, '23456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'))
{
for(int j = 0; binario[j]; j++)
{
cifras = j+1;
}

// ----------------------------------------------
// Pasamos el binario al decimal correspondiente

int i = 0;
int k = cifras-1;

while(i <= cifras-1)
{
decimal += (binario[k]-'0')*pow(2,i);
k--;
i++;
}

cout << "\nEl numero binario: " << binario << " es " << decimal << " en decimal" << endl;
cout << "Volver a menu principal" << endl;
system("read a");
main();

delete[] binario;
} else {
cout << "Valor incorrecto, introduzcalo de nuevo";
system("read a");
ConvertirBinarioADecimal();
}
}

char ConvertirDecAHexSimple(int decimal) // CORRECTO
{
char hexsimpl;

if(decimal == 0)
{
hexsimpl = '0';
} else if(decimal == 1)
{
hexsimpl = '1';
} else if(decimal == 2)
{
hexsimpl = '2';
} else if(decimal == 3)
{
hexsimpl = '3';
} else if(decimal == 4)
{
hexsimpl = '4';
} else if(decimal == 5)
{
hexsimpl = '5';
} else if(decimal == 6)
{
hexsimpl = '6';
} else if(decimal == 7)
{
hexsimpl = '7';
} else if(decimal == 8 )
{
hexsimpl = '8';
} else if(decimal == 9)
{
hexsimpl = '9';
} else if(decimal == 10)
{
hexsimpl = 'A';
} else if(decimal == 11)
{
hexsimpl = 'B';
} else if(decimal == 12)
{
hexsimpl = 'C';
} else if(decimal == 13)
{
hexsimpl = 'D';
} else if(decimal == 14)
{
hexsimpl = 'E';
} else if(decimal == 15)
{
hexsimpl = 'F';
}

return hexsimpl;
}

int ConvertirBinADecSimple(char binario[3]) // CORRECTO
{
int decimal = 0;
int cifras = 3+1;

// ----------------------------------------------

int i = 0;
int k = cifras-1;

while(i <= cifras-1)
{
decimal += (binario[k]-'0')*pow(2,i);
k--;
i++;
}

return decimal;
}

void ConvertirBinarioAHexadecimal() // CORRECTO
{
char *binario;
binario = new char[32];
char *hexadecimal;
hexadecimal = new char[32];
int cifras;
int restante;

cout << "Indique el numero binario: "; cin >> binario;

if(strchr(binario, '23456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ'))
{
for(int j = 0; binario[j]; j++)
{
cifras = j+1;
}

if(cifras%4 != 0)
{
char *copia;
copia = new char[cifras+(4-cifras%4)];
restante = 4-cifras%4;

for(int i = 0; i < restante ; i++)
{
copia[i] = '0';
}

for(int i = restante; i < (cifras + restante); i++)
{
copia[i] = binario[i-restante];
}

int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras + restante; i+= 4)
{
char cpy[4] = {copia[i-4], copia[i-3], copia[i-2], copia[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
delete[] copia;

} else {
int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras; i+= 4)
{
char cpy[4] = {binario[i-4], binario[i-3], binario[i-2], binario[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
}


cout << "El numero binario " << binario << " es " << hexadecimal << " en hexadecimal" << endl;
delete[] binario;
delete[] hexadecimal;
cout << "Volver a menu principal" << endl;
system("read a");
main();
} else {
cout << "Valor incorrecto, introduzcalo de nuevo";
system("read a");
ConvertirBinarioAHexadecimal();
}
}

void ConvertirDecimalABinario() // CORRECTO
{
int decimal, dec;
char binario[64];
char *copia;
copia = new char[32];

cout << "Indique el numero decimal: "; cin >> dec;
cout << endl;

decimal = dec;

int j = 0;

while(decimal/2 >= 1)
{
if(decimal%2 == 0)
{
binario[j] = '0';
} else
{
binario[j] = '1';
}
decimal /= 2;
j++;
}

binario[j] = '1';

int i = 0;
for(int d = j; d >= 0; d--)
{
copia[i] = binario[d];
i++;
}

cout << "El numero decimal " << dec << " es " << copia << " en binario" << endl;
delete[] copia;

cout << "Volver a menu principal" << endl;
system("read a");
main();

}

void ConvertirDecimalAHexadecimal() // CORRECTO
{
int decimal, dec, cifras, restante;
char binario[64], *copia, *hexadecimal;
copia = new char[32];
hexadecimal = new char[32];

cout << "Indique el numero decimal: "; cin >> dec;

decimal = dec;

int j = 0;

// Convertimos decimal a binario
while(decimal/2 >= 1)
{
if(decimal%2 == 0)
{
binario[j] = '0';
} else
{
binario[j] = '1';
}
decimal /= 2;
j++;
}

binario[j] = '1';

int i = 0;
for(int d = j; d >= 0; d--)
{
copia[i] = binario[d];
i++;
}

// Convertimos binario a hexadecimal

for(int j = 0; copia[j]; j++)
{
cifras = j+1;
}

if(cifras%4 != 0)
{
char *ncopia;
ncopia = new char[cifras+(4-cifras%4)];
restante = 4-cifras%4;

for(int i = 0; i < restante ; i++)
{
ncopia[i] = '0';
}

for(int i = restante; i < (cifras + restante); i++)
{
ncopia[i] = copia[i-restante];
}

int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras + restante; i+= 4)
{
char cpy[4] = {ncopia[i-4], ncopia[i-3], ncopia[i-2], ncopia[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
delete[] ncopia;

} else {
int pos = 0;
int dec = 0;
for(int i = 4; i <= cifras; i+= 4)
{
char cpy[4] = {copia[i-4], copia[i-3], copia[i-2], copia[i-1]};
dec = ConvertirBinADecSimple(cpy);
hexadecimal[pos] = ConvertirDecAHexSimple(dec);
pos++;
}
}

cout << "El numero decimal " << dec << " es " << hexadecimal << " en hexadecimal" << endl;
delete[] copia;
delete[] hexadecimal;
cout << "Volver a menu principal" << endl;
system("read a");
main();
}

void ConvertirHexadecimalABinario() // CORRECTO SALVO AL IMPRIMIR
{
char *hexadecimal;
hexadecimal = new char[32];
int cifras = 0;

cout << "Indique el numero hexadecimal: "; cin >> hexadecimal;
cout << endl;

for(int i = 0; hexadecimal[i]; i++)
{
cifras = i+1;
}
char binario[cifras][4], **binsimpl;
binsimpl = new char*[cifras-1];
binsimpl[cifras] = new char[5];

// -------------------------------------

for(int j = 0; j < cifras; j++)
{
binsimpl[j] = ConvertirHexABinSimple(hexadecimal[j], binario[j]);
}

cout << "El numero hexadecimal: " << hexadecimal << " es " << binsimpl[0] << " en binario" << endl;
cout << "Volver a menu principal" << endl;
system("read a");
main();
delete[] binsimpl;
delete[] hexadecimal;
}

char* ConvertirHexABinSimple(char hexa, char* bin) // CORRECTO
{

if(hexa == '0')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == '1')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == '2')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '1';
bin[3] = '0';
} else if(hexa == '3')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == '4')
{
bin[0] = '0';
bin[1] = '1';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == '5')
{
bin[0] = '0';
bin[1] = '1';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == '6')
{
bin[0] = '0';
bin[1] = '0';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == '7')
{
bin[0] = '0';
bin[1] = '1';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == '8')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == '9')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == 'A')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '1';
bin[3] = '0';
} else if(hexa == 'B')
{
bin[0] = '1';
bin[1] = '0';
bin[2] = '1';
bin[3] = '1';
} else if(hexa == 'C')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '0';
bin[3] = '0';
} else if(hexa == 'D')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '0';
bin[3] = '1';
} else if(hexa == 'E')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '1';
bin[3] = '0';
} else if(hexa == 'F')
{
bin[0] = '1';
bin[1] = '1';
bin[2] = '1';
bin[3] = '1';
}


return bin;
delete[] bin;

}

void ConvertirHexadecimalADecimal() // CORRECTO
{
char *hexadecimal;
hexadecimal = new char[32];
int decimal = 0, cifras = 0;

cout << "Indique el numero hexadecimal: "; cin >> hexadecimal;
cout << endl;

if(strchr(hexadecimal, 'GHIJKLMNÑOPQRSTUVWXYZ'))
{
for(int j = 0; hexadecimal[j]; j++)
{
cifras = j+1;
}

int k = 0;
int i = cifras-1;

while(i >= 0)
{
if(hexadecimal[i] >= 0 && hexadecimal[i] != 'A' && hexadecimal[i] != 'B' && hexadecimal[i] != 'C' && hexadecimal[i] != 'D' && hexadecimal[i] != 'E' && hexadecimal[i] != 'F')
{
decimal += (hexadecimal[i]-'0')*pow(16,k);
} else {
decimal += (hexadecimal[i]-'7')*pow(16,k);
}
k++;
i--;
}

cout << "El hexadecimal " << hexadecimal << " es " << decimal << " en decimal" << endl;
cout << "Volver a menu principal" << endl;
system("read a");
main();
delete[] hexadecimal;
} else {
cout << "Valor incorrecto, introduzcalo de nuevo";
system("read a");
ConvertirHexadecimalADecimal();
}

}

Permalink Dejar un comentario

Desarrollando un nuevo programa

septiembre 30, 2009 at 11:13 pm (Cpp, Programación)

Buenas!, El otro día tuve informática y empezamos a “dar” las notaciones decimal, hexadecimal y binaria, y el profesor me dio la idea de desarrollar un programa que convierta numeros de una notación a otra, estoy trabajando en ello, porque hay partes del algoritmo que no me resultan bien, pero bueno, la verdad es que va muy bien, con pequeños fallos, es obvio que yo ya conocia las notaciones, si no no me habría aventurado a desarrollar el programa en C++ .. Lo colgaré en cuanto lo termine y compruebe que funciona, por cierto, tambien tengo que contaros otras novedades, atentos al blog!.

Saludoos!.

Permalink Dejar un comentario

Buscar Caracter y Calcular la Longitud de una Cadena C++

septiembre 18, 2009 at 12:32 am (Cpp)

Bueno, leyendo un manual de C++ proponian unos problemas (2), yo los he hecho en un solo programa, los problemas consistían en buscar un caracter concreto en una cadena, dando como parámetros la cadena y el caracter y el otro problema consistía en calcular la longitud de una cadena dando como parámetro un puntero a char, aquí está el programa:

V1:
#include
using namespace std;

int LongitudCadena(char *cadena[]);
int BuscaCaracter(char cadena[], char caracter[]);

int main()
{
char *cadena = "Saambala";
char Cadena[9] = "Saambala";
char caracter[2] = "m";
cout << "Logitud de " << cadena << ": " << LongitudCadena(&cadena) << endl;
cout << "El caracter m en la cadena " << Cadena << " se encuentra en la posicion: " << BuscaCaracter(Cadena, caracter) << endl;
system("pause");
}

int LongitudCadena(char *cadena[])
{
int j = 0;
while(cadena[j] != NULL) { j++; }
return (j+1)/2;
}

int BuscaCaracter(char cadena[], char caracter[])
{
int i = 0, j = 0;
while(cadena[i] != caracter[j]) { i++; }
return i+1;
}

Con un if en vez de un while, o un for también habría funcionado, pero bueno, vi una especie de plantilla con while y decidí hacerlo así. La longitud de cadena tuve que dividirla entre 2, no se por qué me da el doble del resultado O.o. Ya he comprendido la utilidad de los punteros, aunque aun no les he aprendido a sacar mucho partido.. Se para qué y cómo se usan (tipo *puntero; puntero = &variablequeapuntan; *puntero++ equivale a variablequeapuntan++, puntero++ aumenta en 1 la posición que apuntan y como parámetro de funciones siempre poner la direccion a la que apuntan, &puntero. RESUMEN), pero aun no veo DONDE se usan xD. En otro ejemplo se podría apreciar que un vector de punteros a char (ejemplo) solo necesita una dimensión, en cambio un array char, necesita 2 dimensiones para almacenar 12 meses con 11 carácteres de máximo cada uno, ejemplo, repito, y bueno, todo esto sobre los punteros, iré probándolos mas a menudo =D.

Gracias.

Permalink Dejar un comentario

Gestor de Empleados C++

septiembre 17, 2009 at 2:38 pm (Cpp)

Buenas, pues hoy quiero presentaros mi último programa.. Es bastante simple de momento, pero tiene varias funciones que me parecieron necesarias.. El programa es un gestor de empleados diseñado para cualquier empresa, consta de 7 funciones entre las que destacan añadir empleado, borrar empleado, mandar mensajes entre empleados y leer mensajes.. Son bastante simples, pero en la función de mandar mensaje tengo un error identificado en 4 líneas continuas.. El programa me parece que está bastante logrado, y bien pensado, ya me diréis algo, mientras tanto iré mejorándolo.

V1:

#include <stdio.h>
#include <iostream>
using namespace std;

int Empleados = 0;
int plantilla = Empleados;
char sn[3];
int opcion;

//Todas las funciones necesarias para el programa
void AnadirEmpleado();
void BorrarEmpleado();
void ConsultarNumEmpleado();
void ConsultarTelefonos();
void ConsultarRango();
void MandarMensaje();
void LeerMensajes();
void ConsultarNumMensajes();

struct Plantilla
{
char Nombre[32];
char Apellido[32];
int TelefonoMovil;
int TelefonoParticular;
int EmpleadoNum;
int totalmensajes;
Plantilla(){ totalmensajes = 0; }
struct BandejaDeEntrada
{
char Texto[499];
char subject[32];
char destinoNombre[32];
char destinoApellido[32];
char remiteNombre[32];
char remiteApellido[32];
} Mensajes[50];
float Sexo;
char Direccion[32];
float Rango; //1 = empleado, 2 = ejecutivo, 3 = directivo
} Plantilla[200];

int main()
{
system("cls");
int opc;

cout << "Bienvenido al Gestor de Empleados, A continuacion seleccione la gestion que desee." << endl;
cout << "1.- Anadir Empleado" << endl << "2.- Borrar Empleado" << endl << "3.- Consultar Numero de Empleado" << endl;
cout << "4.- ConsultarTelefonos" << endl << "5.- Consultar Cargo" << endl << "6.- Mandar Mensaje" << endl;
cout << "7.- Consultar Mensaje" << endl << "8.- Consultar Bandeja de Entrada" << endl;
cin >> opc;

switch(opc)
{
case 1:
AnadirEmpleado();
break;
case 2:
BorrarEmpleado();
break;
case 3:
ConsultarNumEmpleado();
break;
case 4:
ConsultarTelefonos();
break;
case 5:
ConsultarRango();
break;
case 6:
MandarMensaje();
break;
case 7:
LeerMensajes();
break;
case 8:
ConsultarNumMensajes();
default:
cout << "Opcion incorrecta" << endl;
system("pause");
main();
break;
}
}

void AnadirEmpleado()
{

system("cls");
cout << "Nombre: ";
cin >> Plantilla[Empleados].Nombre;
cout << "\nApellido: ";
cin >> Plantilla[Empleados].Apellido;
cout << "\nDireccion: ";
cin >> Plantilla[Empleados].Direccion;
cout << "\nTelefono Movil: ";
cin >> Plantilla[Empleados].TelefonoMovil;
cout << "\nTelefono Particular: ";
cin >> Plantilla[Empleados].TelefonoParticular;
cout << "\nSexo (H=1, M=2): ";
cin >> Plantilla[Empleados].Sexo;
cout << "\nCargo (Empleado=1, Ejecuto=2, Directivo=3): ";
cin >> Plantilla[Empleados].Rango;
Plantilla[Empleados].EmpleadoNum = Empleados+1;
cout << "\n\nAnadir? (s/n): ";
cin >> sn;
if(sn == "s" || sn == "S")
{
FILE *fichero;
char NombreFichero[64] = "Plantilla[Empleados].Nombre.txt";
fichero = fopen(NombreFichero, "w");
cout << "Nombre: " << Plantilla[Empleados].Nombre << endl;
cout << "Apellido: " << Plantilla[Empleados].Apellido << endl;
cout << "Direccion: " << Plantilla[Empleados].Direccion << endl;
cout << "Telefono Movil: " << Plantilla[Empleados].TelefonoMovil << endl;
cout << "Telefono Particular: " << Plantilla[Empleados].TelefonoParticular << endl;
cout << "Sexo (H=1, M=2): " << Plantilla[Empleados].Sexo << endl;
cout << "Cargo (Empleado=1, Ejecuto=2, Directivo=3): " << Plantilla[Empleados].Rango << endl;
cout << "Numero de Empleado: " << Plantilla[Empleados].EmpleadoNum << endl;
cout << "Numero de Mensajes: " << Plantilla[Empleados].totalmensajes << endl;
fclose(fichero);
cout << "Empleado Anadido con exito, redireccionando al menu principal";
system("pause");
main();
} else {
cout << "Empleado NO anadido, redireccionando al menu principal" << endl;
system("pause");
main();
}
Empleados += 1;
plantilla += 1;
}

void BorrarEmpleado()
{
char Nombre[32];
int NumEmpl;
system("cls");
cout << "Nombre: ";
cin >> Nombre;
if(Nombre)
{
for(int i = 0; i == Empleados; i++)
{
if(Plantilla[i].Nombre == Nombre)
{
Plantilla[i] = Plantilla[Empleados];
plantilla -= 1;
cout << "\n\nEmpleado Borrado con exito, redireccionando a menu principal" << endl;
system("pause");
main();
}
}
} else {
cout << "Numero de Empleado: ";
cin >> NumEmpl;
if(!NumEmpl)
{
cout << "\nDebe introducir al menos un parametro, redireccionando al menu de borrar empleado." << endl;
system("pause");
system("cls");
BorrarEmpleado();
} else {
Plantilla[NumEmpl] = Plantilla[Empleados];
plantilla -= 1;
cout << "\n\nEmpleado Borrado con exito, redireccionando a menu principal" << endl;
system("pause");
main();
}
}
}

void ConsultarNumEmpleado()
{
char Nombre[32];
char Apellido[32];
system("cls");
cout << "Indique el nombre del empleado: ";
cin >> Nombre;
cout << "\nIndique el apellido del empleado :";
cin >> Apellido;
if(Nombre && Apellido)
{
for(int i = 0; i == Empleados; i++)
{
if(Plantilla[i].Nombre == Nombre && Plantilla[i].Apellido == Apellido)
{
cout << i << "es el numero de identificacion del empleado " << Plantilla[i].Nombre
<< " " << Plantilla[i].Apellido << endl;
cout << "Para realizar cualquier otra gestion ve al menu principal, redireccionando" << endl;
system("pause");
main();
} else {
continue;
}
}
} else {
cout << "\nDebe introducir el nombre y el apellido del empleado, redireccionando al menu de consultar empleado" << endl;
system("pause");
ConsultarNumEmpleado();
}
}

void ConsultarTelefonos()
{
char Nombre[32];
char Apellido[32];
int NumEmp;
system("cls");

cout << "Introduzca el Nombre del empleado: ";
cin >> Nombre;
cout << "\nIntroduzca el Apellido del empleado: ";
cin >> Apellido;
if(!Nombre || !Apellido)
{
cout << "\nO si no, introduzca el numero de empleado: ";
cin >> NumEmp;
if(!NumEmp)
{
cout << "\nDebe introducir al menos el nombre y apellido o el numero de empleado, redireccionando al menu de consulta de telefonos" << endl;
system("pause");
ConsultarTelefonos();
} else {
cout << "\nTelefono movil: " << Plantilla[NumEmp].TelefonoMovil << endl;
cout << "Telefono particular: " << Plantilla[NumEmp].TelefonoParticular << endl;
cout << "Redireccionando al menu principal" << endl;
system("pause");
main();
}
} else {
for(int i = 0; i == Empleados; i++)
{
if(Plantilla[i].Nombre == Nombre && Plantilla[i].Apellido == Apellido)
{
cout << "\nTelefono movil: " << Plantilla[i].TelefonoMovil << endl;
cout << "Telefono particular: " << Plantilla[i].TelefonoParticular << endl;
cout << "Redireccionando a menu principal" << endl;
system("pause");
main();
} else {
continue;
}
}
}
}

void ConsultarRango()
{
char Nombre[32];
char Apellido[32];
int NumEmp;
system("cls");

cout << "Introduzca el Nombre del empleado: ";
cin >> Nombre;
cout << "\nIntroduzca el Apellido del empleado :";
cin >> Apellido;
if(!Nombre || !Apellido)
{
cout << "\nEscriba el numero de empleao: ";
cin >> NumEmp;
if(!NumEmp)
{
cout << "Debe introducir el nombre y apellido o el numero de empleado, redireccionando al menu de consulta de cargo" << endl;
system("pause");
ConsultarRango();
} else {
cout << "El cargo del empleado es (1=Empleado, 2=Ejecutivo, 3=Directivo): " << Plantilla[NumEmp].Rango << endl;
cout << "Redireccionando al menu principal" << endl;
system("pause");
main();
}
} else {
for(int i = 0; i == Empleados; i++)
{
if(Plantilla[i].Nombre == Nombre && Plantilla[i].Apellido == Apellido)
{
cout << "El cargo del empleado es (1=Empleado, 2=Ejecutivo, 3=Directivo): " << Plantilla[i].Rango << endl;
cout << "Redireccionando al menu principal" << endl;
system("pause");
main();
} else {
continue;
}
}
}
}

void MandarMensaje()
{
char Texto[499];
char subject[32];
char destinoNombre[32];
char destinoApellido[32];
char remiteNombre[32];
char remiteApellido[32];
system("cls");

cout << "Escribe el nombre del destinatario: ";
cin >> destinoNombre;
cout << "\nEscribe el apellido del destinatario: ";
cin >> destinoApellido;
cout << "\nEscribe tu nombre: ";
cin >> remiteNombre;
cout << "\nEscribe tu apellido: ";
cin >> remiteApellido;
cout << "\nEscribe el asunto del mensaje: ";
cin >> subject;
cout << "\nEscribe el texto del mensaje: " << endl;
cin >> Texto;
if(destinoNombre && destinoApellido && remiteNombre && remiteApellido && subject && Texto)
{
cout << "\n\nDesea enviar el mensaje? s/n: ";
cin >> sn;
if(sn == "S" || sn == "s")
{
for(int i = 0; i == Empleados; i++)
{
if(Plantilla[i].Nombre == destinoNombre && Plantilla[i].Apellido == destinoApellido)
{
Plantilla[i].Mensajes[Plantilla[i].totalmensajes].remiteNombre = remiteNombre;
Plantilla[i].Mensajes[Plantilla[i].totalmensajes].remiteApellido = remiteApellido;
Plantilla[i].Mensajes[Plantilla[i].totalmensajes].subject = subject;
Plantilla[i].Mensajes[Plantilla[i].totalmensajes].Texto = Texto;
Plantilla[i].totalmensajes += 1;
} else {
continue;
}
}
} else {
cout << "\nEl mensaje no ha sido enviado, redireccionando al menu de enviar mensaje" << endl;
system("pause");
MandarMensaje();
}
} else {
cout << "\nDebes introducir todos los parametros, redireccionando a menu de mandar mensaje" << endl;
system("pause");
MandarMensaje();
}
}

void LeerMensaje()
{
char Nombre[32];
char Apellido[32];
int NumMensaje;
system("cls");

cout << "Introduzca el nombre: ";
cin >> Nombre;
cout << "\nIntroduzca el apellido: ";
cin >> Apellido;
cout << "\nIntroduzca el numero de mensaje a leer: ";
cin >> NumMensaje;
if(!Nombre || !Apellido || !NumMensaje)
{
cout << "\nDebe introducir todos los parametros, redireccionando al menu de leer mensaje" << endl;
system("pause");
LeerMensaje();
} else {
for(int i = 0; i == Empleados; i++)
{
if(Plantilla[i].Nombre == Nombre && Plantilla[i].Apellido == Apellido)
{
cout << "Asunto: " << Plantilla[i].Mensajes[NumMensaje].subject << endl;
cout << "Remitente: " << Plantilla[i].Mensajes[NumMensaje].remiteNombre << " " << Plantilla[i].Mensajes[NumMensaje].remiteApellido << endl;
cout << "Texto: " << Plantilla[i].Mensajes[NumMensaje].Texto << endl;
cout << "Redireccionando al menu principal" << endl;
system("pause");
main();
}
}
}
}

Bueno, el programa es bastante extenso, y tiene errores entre las líneas 325-328, el error es

ISO C++ forbids assignment of arrays

Gracias por leerme, espero que os esté resultando agradable. Saludos.

Permalink Dejar un comentario

Retomando C++

septiembre 15, 2009 at 10:53 pm (Cpp, Programación)

Buenas a todos, sólo unos pocos saben que estudié C++ hace unos meses, y lo estudié durante otro mes, que me bastó para llegar a tener conocimientos plenos sobre la mayoría de este lenguaje, quedándome antes de empezar con las clases y la herencia.. Bueno, el caso es que siempre he sido muy ambicioso en cuanto a conocimientos, y, por lo tanto, he retomado el estudio de este sensacional lenguaje de programación, para mi gusto, el mas potente y manejable de todos, aunque también unos en los que mas hay que esforzarse, ya que al ser de muy bajo nivel se requieren mas líneas para un simple sentencia en Visual Basic, por ejemplo.. Mediante vaya avanzando en mis estudios iré colocando algunos ejemplos de programas o problemas que me vayan surgiendo, y asi, podáis comentar.. Los que me leáis xD.. Ahora el clásico “Hola Mundo”, para calentar motores:

#include <iostream>
using namespace std;

int main()
{
cout << "Hola mundo" << endl;
system("pause"); // Solo para windows.. Linux ejecuta de otra manera, por asi decirlo.
}

Ahora explicaré cada línea, para la gente que no esté muy puesta en el tema:

#include <iostream> -> Esta línea no es necesaria, pero viene bien para familiarizarse con c++ y sus métodos, simplemente incluye una libreria estándar que viene con todos los compiladores C++ que cumplan la regla ANSI.

using namespace std; -> Esta línea hace que sea posible escribir “cout <<” sin necesidad de poner “std::” delante, pasa lo mismo con todos los elementos de esta libreria.

“” -> Una línea vacía, insignificante para el programa, simplemente cuenta como una línea más, aunque si es práctico a la hora de leer el programa por el programador, lo hace mas visual y agradable de leer.

int main() -> Esta línea es muy especial, está presente en todos los programas C++ y es la función que toma el mando en cuanto el programa es ejecutado, la primera palabra: int en este caso, indica el tipo de valor de retorno de esta función, en este caso entero, podría ser char (carácter), pero no con la función “main()”, siempre debe devolver entero, la segunda palabra: main en este caso, es el nombre de la función, el que será usado para invocar o llamar a la función, nunca veremos que sea llamada la función “main”, al menos de momento, si seguimos viendo los elementos de esta línea vemos “()”, son paréntesis que encierran a los argumentos requeridos por la función, “main” no admite parámetros, de ahí que la línea esté vacía, también podría ponerse un “main(void)”, pero es menos práctico.

{ -> Una llave, aparentemente no hace nada, simplemente encierra el cuerpo de la función, donde irán recogidas las sentencias y expresiones de la función.

cout << “Hola mundo” << endl; -> La primera sentencia de nuestro programa, se diferencia porque termina con un “;”, veamos elemento a elemento esta línea: cout << es el “comando” usado para imprimir texto en pantalla, si no hubiéramos escrito “using namespace std;” deberíamos haber escrito “std::cout <<“, es mas largo y difícil de recordar.. Es un elemento simple, que es muy usado en c++ en general, siguiente: “Hola mundo”, todo lo escrito entre comillas dobles será el texto impreso en pantalla, simple. Lo siguiente es << endl, ésto es el “comando” que finaliza la línea y hace que lo siguiente que se imprima en pantalla salga en una línea mas abajo, puede traducirse como “endline” = “endl”. Más fácil de recordar.

system(“pause”) ; // Solo para windows.. Linux ejecuta de otra manera, por asi decirlo. -> Otra sentencia, esta sirve para pausar el programa, sin esta línea el programa se cerraria de inmediato bajo una plataforma windows, al poner esto en la línea de comandos aparecerá un “Pulsa cualquier boton para continuar”, asi podremos leer el texto impreso en pantalla. Lo escrito después de // se llama comentario, el programa lo ignora y tiene mera función de guía, ya que es útil para el programador, y asi entender mejor el código. Es mejor acostumbrarse a comentar los programas y asi explicarlos, para ti mismo incluso.

} -> Cierra el cuerpo de la función, nada mas que comentar.

Bueno, con esto terminamos la explicación del código, espero que haya quedado claro y entendido, el primer programa, como véis, es muy simple y clásico (hola mundo xD). Seguiré publicando temas de este tipo, mientras vaya avanzando.

Un Saludo, y gracias por leerme.

Permalink Dejar un comentario