|
Esta sección te permite ver todos los posts escritos por este usuario. Ten en cuenta que sólo puedes ver los posts escritos en zonas a las que tienes acceso en este momento.
Mensajes - ProfesorX
Páginas: 1 ... 5 6 [7] 8 9 ... 32
151
« en: Miércoles 17 de Agosto de 2011, 23:05 »
Si borras la pantalla, debes volber a pulsar un botón desde el teclado virtual, y luego ya puedes seguir con el normal...
Por lo que comentas, parece que no estas capturando el evento Keypress en el boton de borrado de pantalla, ya antes te dije que debes capturar el evento Keypress para todos tus controles, inclusive para el formulario, no solo para los botones de los digitos, ya que el evento Keypress funciona solo si el control tiene el foco, pero si pulsas otro boton que no sea el digito, y no capturas el evento Keypress para ese boton, logicamente no te reconocera el que pulses un digito. Puedes hacerlo desde el diseñador (lo mas recomendable) o en el metodo Load de tu formulario, te dejo a continuacion un ejemplo de como hacerlo manualmente en el metodo Load, suponiendo que el boton de borrado se llama btClear y el metodo que controla el eventp KeyPress se llama bt_Digito_KeyPress como en tu ejemplo anterior: private void Form1_Load(object sender, EventArgs e) { etPantalla.Enabled = false; // Ya no utilices el & para poder // capturar el evento keypress en el metodo // bt_Digito_KeyPress btDigito1.Text = "1"; btDigito2.Text = "2"; // Añades el evento KeyPress al boton de borrado this.btClear.KeyPress += new KeyPressEventHandler(this.bt_Digito_KeyPress); // Añades el evento KeyPress al Formulario this.KeyPress += new KeyPressEventHandler(this.bt_Digito_KeyPress); }
Saludos
152
« en: Martes 16 de Agosto de 2011, 17:14 »
con respecto a devcpp no entiendo, la libreria se descarga e instala automaticamente desde el menu herramientas, igual hay que modificar las opciones que comentas para poder compilarla? un saludo
Cuando descargas la libreria con el downloader que viene con dev-cpp, lo que hace es descargar y descomprimir el archivo en donde se guardan las librerias de mingw, asi que si, debes modificar las opciones de compilacion, especificamente las de linker, ya que el error es de linker (enlace), de tal forma que pueda encontrar el archivo liballeg_s.a como te dije antes, aunque me parece que el archivo no se llama asi, sino liballeg.a, por eso te comentaba que buscaras el archivo, y si no lo encuentras, pero encuentras uno con nombre parecido, uses el que encontraste, y modifiques la linea de -lalleg_s a -lnombre_de_la_libreria en tu proyecto. Tambien como dije antes verifica que se encuentre en donde estan el resto de archivos .a, si no esta ahi, sino en otro directorio (probablemente un sub-directorio dentro del directorio de librerias), deberas añadir la ruta del sub-directorio completa a la lista de directorios de busqueda de librerias de dev-cpp, tiene mucho que no uso dev-cpp, pero me parece que puedes modificar los directorios de manera global (o sea, para todos los proyectos) o solo para el proyecto actual, mi recomendacion es que lo modifiques de manera global, asi cada vez que creas un nuevo proyecto no tendras que añadir el directorio manualmente. Saludos
153
« en: Lunes 15 de Agosto de 2011, 19:36 »
El problema viene de la siguiente linea: etPantalla.Text += objButton.Text;
estas asignando el valor de la propiedad Text de tu boton a la propiedad Text de tu Textbox, y dado que la propiedad Text contiene "&1", es por eso que añade "&1" al TextBox. Esa es la razon por la que en mi ejemplo yo manejaba el evento click de cada boton por separado, si no lo notaste: private void button1_Click(object sender, EventArgs e) { etPantalla.Text = etPantalla.Text + "1"; }
en lugar de private void button1_Click(object sender, EventArgs e) { Button objButton = (Button)sender; etPantalla.Text += objButton.Text; }
Ya que añades & a la propiedad Text del button, entonces el evento Keypress para ese button ya no es capturado, por eso el case '1' del evento keypress tampoco funciona. Si insistes en utilizar un metodo general llamado btDigito_Click para todos tus eventos de botones en lugar de un metodo individual para cada boton, entonces pense en otra solucion, elimina entonces el & de la propeidad Text del boton, y maneja entonces el eventi keypress desde el metodo general bt_Digito_KeyPress: private void Form2_Load(object sender, EventArgs e) { etPantalla.Enabled = false; // Ya no utilices el & para poder // capturar el evento keypress en el metodo // bt_Digito_KeyPress btDigito1.Text = "1"; btDigito2.Text = "2"; }
private void btDigito_Click(object sender, EventArgs e) { Button objButton = (Button)sender; if (ultimaEntrada != Entrada.DIGITO) // al principio es NINGUNA { if (objButton.Text == "0") return; // return devuelve el control para que otro lo recoja etPantalla.Text = ""; ultimaEntrada = Entrada.DIGITO; comaDecimal = false; } etPantalla.Text += objButton.Text;
}
private void bt_Digito_KeyPress(object sender, KeyPressEventArgs e) {
switch (e.KeyChar) { // Tecla BackSpace (Retroceso) case '\b': if (etPantalla.Text.Length > 0) etPantalla.Text = etPantalla.Text.Substring(0, etPantalla.Text.Length - 1); break; // Ahora que eliminaste el & // si podras capturar el keypress aca case '1': etPantalla.Text = etPantalla.Text + "1"; break; case '2': etPantalla.Text = etPantalla.Text + "2"; break; } }
Pruebalo ahora y comenta como te fue. Saludos
154
« en: Lunes 15 de Agosto de 2011, 18:32 »
Primero que nada, recomendaria que no utilizaras Dev-cpp, es un IDE que no ha sido actualizado desde hace mucho, lo mejor es utilizar Code::Blocks puedes bajar solo el IDE o la version que incluye mingw, aunque yo preferiria solo el IDE y bajar MingW por aparte, a dia de hoy 15 de agosto de 2011, la version mas reciente del instalador de mingw es la 20110802. Claro, despues tendrias que bajar Allegro directamente de su pagina y compilarlo tu mismo tambien en su version mas reciente que a dia de hoy es la 5.0.4. Se que es mucho trabajo para alguien que comienza como sospecho que es tu caso, pero el beneficio que obtendras a la larga sera mayor, ya que estaras trabajando con la ultima version de desarrollo de las herramientas, y si mas adelante aparece una version mas nueva, podras rapidamente actualizarla. Bueno, regresando a tu problema, y si insistes en trabajar con dev-cpp, te dire que el primer error: cannot find -lalleg_s se debe a que tu proyecto no encuentra la libreria allegro, debes especificar el nombre correcto de la libreria, ademas de la ruta (directorio) donde se encuentra. Busca si tienes un archivo llamado liballeg_s.a, fijate en que directorio se encuentra y añade la ruta del directorio en las opciones del linker. Si tu archivo de libreria tiene otro nombre, por ejemplo liballeg.a, entonces debes modibicar las opciones de linker de tal forma que digan -lalleg en lugar de -lalleg_s, (nota como al añadir la libreria a las opciones del linker, debes eliminar del nombre del archivo el prefijo lib y la extension .a) El segundo error: [Linker error] undefined reference to `WinMain@16' es debido a que tratas de compilar un programa en modo ventana como si fuera un programa de consola. Si quieres un programa de ventana, debes utilizar WinMain() en lugar de main() para el codigo principal. Busca en google sobre WinMain para mas informacion. Saludos y suerte
155
« en: Lunes 15 de Agosto de 2011, 06:02 »
Hola picyo, hay una manera facil, y no muy bien documentada de hacerlo en C#, si añades un "&" antes de la letra/numero en la propiedad Text de tu button, podras utilizar esa letra/numero para "pulsar" esa tecla como si utilizaras el raton (mouse) para pulsar el boton. Te sugiero ademas que deshabilites (Enabled = false) tu textbox para evitar que "manualmente" modifiques el contenido de tu textbox, y mejor haz la modificacion del contenido com puros eventos y botones, añadiendo la funcionalidad que desees en los diferentes eventos, creando un metodo "general" para manejar tu Keypress event, tanto del formulario como de los botones. En el siguiente ejemplo, te muestro como deberias manejar los eventos para teclas numericas y la tecla BackSpace (retroceso) con la que podrias borrar el contenido de tu textbox cuando lo tengas deshabilitado. Para añadir la funcionalidad de otras teclas (+, -, *, etc.) simplemente añade otros case dentro del metodo KeyPress_General, añade el metodo al evento Keypress de tu formulario y botones en tiempo de diseño. Puedes modificar la propiedad Text de todos tus botones dentro del metodo Form_Load, o lo puedes hacer en tiempo de diseño tambien, recuerda colocar un & antes de cada numero, ejemplo: &1, &2, &3, &4, etc. private void Form1_Load(object sender, EventArgs e) { textBox1.Enabled = false; // Puedes hacerlo en tiempo de diseño si lo deseas button1.Text = "&1"; button2.Text = "&2"; }
private void button1_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + "1"; }
private void button2_Click(object sender, EventArgs e) { textBox1.Text = textBox1.Text + "2"; }
// Añade el siguiente metodo al evento Keypress de tu formulario // y tus botones private void KeyPress_General(object sender, KeyPressEventArgs e) { switch (e.KeyChar) { // Tecla BackSpace (Retroceso) case '\b': if (textBox1.Text.Length > 0) textBox1.Text = textBox1.Text.Substring(0, textBox1.Text.Length - 1); break; } }
Saludos
156
« en: Lunes 15 de Agosto de 2011, 05:05 »
Creo que el problema esta en como estoy usando en int, pero la verdad no le encuentro la vuelta.
Exacto, ese es el problema, el uso de int Dado que el resultado puede dar valores con punto decimal (flotantes), lo mas correcto es definir todas tus variables de tipo float o double, para evitar que el resultado se "trunque" de manera incorrecta. Aun asi, debes tomar en cuenta que esto no garantiza que obtendras un resultado exacto al 100%, debido al redondeo de las variables float, pero obtendras un resultado mas exacto que si utilizaras variables enteras. Editado: por la rapidez de mi respuesta, no note un detalle adicional, el uso de ^ para elevar al cuadrado, en C/C++ no se utiliza ^ para elevar a una "n" potencia, la manera correcta para elevar al cuadrado es utilizar "variable * variable" o la funcion pow(variable, 2) que esta definida en la libreria math.h Saludos
157
« en: Viernes 12 de Agosto de 2011, 02:10 »
Las propiedades son un tipo especial de variable que se utilizan para seguir el principio de Encapsulamiento del paradigma de la Programacion orientada a objetos (POO)En C# existe una construccion especial utilizando get/set para crear propiedades de lectura/escritura explicitamente y conservar independiente tus variables locales o internas de la clase (privadas) Mas informacion sobre clases y propieidades http://es.wikipedia.org/wiki/Clase_%28programaci%C3%B3n_orientada_a_objetos%29Ejemplo del uso de get/set para definir propiedades de lectura y de lectura/escritura public class Articulo { // Variables privadas, solo modificables dentro de la clase // siguiendo el principio de encapsulacion private string id; private string descripcion;
public Articulo(string id, string descripcion) { this.id = id; this.descripcion = descripcion; }
// Propiedad de lectura (get) para acceder a la // variable privada public string ID { get { return id; } }
// Propiedad de lectura/escritura (get/set) para acceder // a la variable privada public string Descripcion { get { return descripcion; }
// Se utiliza la palabra value dentro de set // para escribir en la variable set { descripcion = value; } } }
Saludos
158
« en: Miércoles 10 de Agosto de 2011, 03:19 »
Otra vez olvidaste las equiquetas code, no olvides usarlas, puedes insertarla facilmente con el boton con el simbolo # de la barra de herramientas. Bueno, regresando a tu problema no se si entendi bien tu explicacion, pero si lo que deseas es repetir el pago en caso de que no sea suficiente, podrias usar un ciclo do..while para hacerlo. Un detalle adicional, tu condicion para dar el cambio esta incorrecta, porque no toma en cuenta que te den la cantidad exacta, solo si te dan una cantidad mayor, la condicion correcta deberia ser pago >= total. static void Main(string[] args) { int product = 0, i; double imp = 0.12, cambio = 0, sub_total = 0, pago, venta = 0, iva = 0, total = 0; double[] monto_v = new double[4];
for (i = 0; i < 4; i++) {
Console.Write(" Ingrese el Monto de su Venta: "); monto_v[i] = double.Parse(Console.ReadLine()); product++;
if (monto_v[i] > 0) {
venta = monto_v[i] + venta; iva = venta * imp; sub_total = venta - iva; total = venta + iva; } } Console.Write(" El Iva es:{0}", iva); Console.ReadLine();
Console.Write(" El Subtotal a Pagar es:{0}", sub_total); Console.ReadLine();
Console.Write(" El Monto a Pagar es:{0}", total); Console.ReadLine();
Console.Write(" La cantidad de productos es:{0}", product); Console.ReadLine(); // Ciclo do..while para repetir el pago cuando no sea // suficiente do { Console.Write(" Introduzca la cantidad de pago: "); pago = double.Parse(Console.ReadLine());
if (pago >= total) {
cambio = pago - total;
Console.Write(" Su Cambio es:{0}", cambio); Console.ReadLine();
Console.Write(" En Caja de haber:{0}", total - cambio); Console.ReadLine();
} else { Console.Write(" FALTA DINERO "); Console.ReadLine(); } } while (pago < total); }
Saludos
159
« en: Martes 9 de Agosto de 2011, 16:03 »
Coloco A ...con i entre corchetes....
Ese es el problema, la i entre corchetes es un bbcode (codigo para formatear mensajes) que representa italica o letra inclinada, no se si lo notaste, pero despues de eso, la letra de tu programa aparecia inclinada. La solucion es utilizar [ code ] [ /code ] (sin espacio en los corchetes) para encerrar tu codigo, o en su defecto poner [ i ], pero lo mejor es usar code, (he corregido tu mensaje original, pero la siguiente ves agrega el code tu mismo)  Ahora respecto a tu programa, lo estas haciendo mal, debes utilizar otro vector para guardar el resultado, y luego utilizar un ciclo for para guardar el resultado de la suma de A + B, no necesitas usar ciclos anidados como lo estabas haciendo, con un ciclo basta. Te dejo el codigo corregido para que veas como debe hacerse. static void Main(string[] args) { int[] A = new int[5]; int[] B = new int[5]; // Vector resultante int[] Suma = new int[5]; int i, j;//, suma = 0;
for (i = 0; i < 5; i++) { Console.Write("ingrerse un numero: "); A[i] = int.Parse(Console.ReadLine()); }
for (j = 0; j < 5; j++) { Console.Write("ingrerse un nuevo valor numerico: "); B[j] = int.Parse(Console.ReadLine());
}
// Suma los elementos A y B en un ciclo // y guardas el resultado en Suma, no necesitas // usar ciclo anidados como hacias antes for (i = 0; i < 5; i++) { Suma[i] = A[i] + B[i]; }
// Imprimes el vector Suma for (i = 0; i < 5; i++) { Console.WriteLine("La suma del elemento {0} es:{1}", i + 1, Suma[i]); } }
Saludos
160
« en: Domingo 7 de Agosto de 2011, 04:02 »
Estas equivocado en tu semantica: me tengo que desascostumbrar a poner Main() en ves de main()
Lo correcto es. "me tengo que acostumbrar a poner Main() en ves de main()." Saludos
161
« en: Domingo 7 de Agosto de 2011, 01:37 »
El problema es que tienes 2 metodos, uno llamado main() (con minuscula) dentro de la clase test, y el otro Main() (con mayuscula) dentro de la clase Program. C# siempre comienza la ejecucion en el metodo Main() (con mayuscula) y dado que ese metodo lo tienes vacio, por eso no ejecuta nada, y solamente se cierra. La solucion es que coloques todo lo que tienes en el metodo main() de la clase test al metodo Main() de la clase program, y borra la clase test. La clase program debe quedar asi: using System; using System.Collections.Generic; using System.Linq; using System.Text;
namespace Craps { class Program { static void Main(string[] args) { Craps Juego = new Craps();
Juego.Jugar();
Console.ReadKey(); } } }
Saludos
162
« en: Miércoles 3 de Agosto de 2011, 16:08 »
Puedes usar las clases StreamReader/StreamWriter del namespace System.IO para leer/esccribir en un archivo. Si deseas usar un cuadro de dialogo para elegir el archivo, puedes utilizar la clase OpenFileDialog, del namespace System.Windows.Forms. Saludos
163
« en: Lunes 1 de Agosto de 2011, 18:33 »
Hola zaiko, he revisado tu codigo, y afortunadamente (o desafortunadamente, como lo quieras ver), el codigo esta correcto y no me marca ningun tipo de error en la parte que mencionabas originalmente. El unico detalle que tuve que hacer, es que elimine las referencias a Crystal Reports, ya que no lo tengo instalado en mi maquina, pero no creo que ese sea el origen del problema, ya que en esa parte no estas utilizando el CR. Quizas el problema se deba a una mala instalacion del NET Framework, o te falta algun Service Pack, mi recomendacion seria que pruebes el sistema en otra maquina, para descartar que sea problema del sistema, y si no te marca error en otra maquina, reinstales el Framework en tu maquina de trabajo, y prueba instalando los parches para el Visual Studio. Solo unos detalles adicionales, recomendaria que copies tu base de datos en el directorio donde esta el ejecutable, asi te evitas el tener que estar cambiando la ruta de acceso a la base de datos en tu codigo: public OleDbConnection ObtenerConexion() { OleDbConnection Conexion = new OleDbConnection(); try { String connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=GS.accdb"; Conexion = new OleDbConnection(connectionString); Conexion.Open(); } catch (Exception e) { Console.WriteLine(e.Message); Conexion.Close(); } return Conexion; }
Tambien añadiria codigo para cerrar tu formulario principal en caso de que lo cierres con la X, ya que se queda ejecutando sin manera de cerrarlo si lo cierras de esa manera: private void Form1_FormClosed(object sender, FormClosedEventArgs e) { Application.ExitThread(); }
Bueno, ojala y que reinstalando el Framework, solucione tu problema. Saludos y
164
« en: Lunes 1 de Agosto de 2011, 05:32 »
Hola zaiko, bienvenido al foro. Bueno, estuve investigando acercar de la Excepcion, y esa excepcion ocurre con punteros no validos (nulos) en codigo no manejado Dado que dices que el error viene al llamar un formulario desde otro formilario, algo debe suceder en el primer formulario que estas llamando un puntero no valido en el segundo formulario, alguna variable mal declarada, o quizas liberada (destruida) en el primer formulario que hace que salte la excepcion en el segundo. Pero desafortunadamente sin ver el codigo completo, me temo que no puedo darte mas ayuda, solo estamos especulando. Si puedes, y aun no lo has resuelto, postea tu codigo completo, si es demasaido largo, sube tu codigo en un archivo .zip como adjunto en tu mensaje, o subelo a algun servicio como megaupload o rapidshare (o algun otro que te guste), y publica tu enlace para que le podamos dar un viztazo. Saludos
165
« en: Miércoles 27 de Julio de 2011, 17:11 »
Hola Ricardoudo. Consejo: utiliza las etiquetas code para encerrar el codigo, ya que mejorla la legibilidad. El error esta en el if: if (b == palabra) { cont++; Console.Write("existe {0} veces ", cont); Console.ReadLine();
}
Solo deberia contener el contador, no el write: if (b == palabra) { cont++; } Console.Write("existe {0} veces ", cont); Console.ReadLine();
Ahora tu codigo funciona bien, pero yo añadiria un Trim, para asegurar que la palabra no comienza o termina con espacios. Ademas de usar un while en lugar de un for. Quedaria asi: static void Main(string[] args) { String oracion, palabra, b, a; int cont = 0, d;
Console.Write("Ingrese una oracion: "); oracion = Console.ReadLine();
Console.Write("Ingrese una palabra: "); palabra = Console.ReadLine(); // Añadiendo Trim() palabra = palabra.Trim();
b = oracion;
// While en lugar de for para no tener que hacer un ciclo completo // letra por letra en toda la oracion while (b.IndexOf(' ') != -1) { d = b.IndexOf(' '); a = b.Substring(0, d); b = b.Substring(d + 1);
if (palabra == a) { cont++; } }
if (b == palabra) { cont++; }
Console.Write("existe {0} veces ", cont); Console.ReadLine();
}
Saludos
166
« en: Martes 26 de Julio de 2011, 15:16 »
me da un error diciendo que c_str() no es miembro de nu.
Esto es porque estas usando la clase CString de la MFC, y el consejo que te dieron es para la clase string de la STL (son dos clases diferentes para manejar strings) Respecto a tu otor problema lamento no poder ayudarte, no tengo experiencia con la MFC  Tendras que preguntar a alguien que tenga experiencia con MFC Saldos
167
« en: Lunes 25 de Julio de 2011, 16:10 »
Me alegra que te haya servido. Bueno, se que probablemente ya lo terminaste, pero como ejercicio hice mi propia funcion para calcular la mascara, esta mas simplificada, y utiliza el operador << (corrimiento de bits a la izquierda) para calcular el valor, y sprintf para convertirlo a cadena, la dejo para ti y para quien en el futuro le pueda servir, estudiala y analizala. #include <cstdio>
char *calcularMascara(int ntipo) { char *mask = new char[16]; int a, b, c, d; a = b = c = d = 0;
for (int i = 1; i <= ntipo; i++) { if (i <= 8) a = a + (1 << (8-i)); else if (i <= 16) b = b + (1 << (16-i)); else if (i <= 24) c = c + (1 << (24-i)); else if (i <= 32) d = d + (1 << (32-i)); }
sprintf(mask, "%03d.%03d.%03d.%03d", a, b, c, d);
return mask; }
int main() { char *mascara;
for (int i = 1; i <= 32; i++) { mascara = calcularMascara(i); printf("%s\n", mascara);
delete mascara; }
return 0; }
Saudos
168
« en: Lunes 25 de Julio de 2011, 01:42 »
se que no es obligacion ni deber suyo ayudarme, pero un favorcillo no estaria de mas
pueden ayudame ? Bueno, mateo135, creo que no es que nadie te quiera ayudar, simplemente nadie sabe como ayudarte, por eso no obtienes respuesta. Por mi parte te dire que no tengo la mas minima idea de lo que haces, ni de lo que quieres hacer, no he trabajado con esas clases y metodos. Asi que si te sirve un "no se" como respuesta, para que no sientas que se te ignora  , aqui lo tienes: NO SE  Saludos y  P.D. Como consejo, deberias buscar en googlel, o en otros foros, quizas tengas mejor suerte, en vez de revivir un tema de hace mas de 6 meses
169
« en: Domingo 24 de Julio de 2011, 09:56 »
Hola de nuevo cazagavilan Tu pregunta es mas de matematicas basicas que de programacion, pero bueno  El nombre lo dice "por ciento" o sea, un porciento o porcentaje es solo una manera de expresar un numero como una fraccion de 100. Simplemente se divide entre 100. O sea siguiendo tu ejemplo, 18% es en realidad 18/100, o sea 0.18. Para obtener el porcentaje de una cantidad (en tu caso un precio) se multiplica la cantidad por el porcentaje (no una suma, una multiplicacion), o sea: precio * (iva / 100) Dado que lo que quieres es obtener el precio mas iva, la operacion seria: total = precio+(precio * (iva / 100)); Saludos y
170
« en: Domingo 24 de Julio de 2011, 08:04 »
Hola de nuevo, disculpa la tardanza en publicar mi respuesta, pero pues el trabajo es primero  Revise tu codigo y si, como te dije antes, estas haciendo mal uso de los punteros, eso es muy comun. Mucha gente cree que es correcto hacer algo como char *nmask; nmask="255."
Sin comprender exactamente que hacen esas lineas. Lo que estas haciendo ahi es crear un puntero a char, y luego hacer que apunte a una direccion de memoria que contiene un valor de cadena constante. Mientras no quieras cambiar el contenido de esa cadena todo ira bien, pero si por algun motivo deseas modificar ese contenido, por ejemplo en tu caso concatenando, inmediatamente estaras sobrescribiendo la memoria con los consecuentes errores. Lo correcto es lo siguiente: char *nmask = new char[5]; strncpy(nmask, "255.", 5);
Aun asi deberas estar al pendiente de no sobrepasar el tamaño de tu memoria dinamica, en este caso 5. En muches lenguajes las cadenas se manejan de manera diferente y si es valido hacer algo como nmask = "255." e incluso nmask = "255." + "255" (concatenacion) El lenguaje C++ si permite asignacion de cadenas con = y concatenacion con +, pero para eso debes usar la clase string. que maneja las cadenas por medio de una clase, y tiene operadores y metodos especiales para manejarlas, pero eso ya es otra historia. El otro error de tu codigo es que cuando usas new char[] asumes que la memoria que obtienes esta limpia (o sea con valor cero) y eso no es asi. Entonces dado que usas strcat, estas concatenando el contenido de basura de tu variable con el valor deseado y si la variable contiene 5 valores basura, y le concatenas 16 mas, obtienes 21, pero el tamaño maximo es de 16 asi que de nuevo sobreescribes la memoria y de nuevo viene el segfault. Lo correcto seria borrar completamente el contenido de la memoria, esto lo puedes hacer por medio de un ciclo o de manera rapida usando memset. Dicho eso, te dejo el codigo con correcciones y anotaciones, lo probe y ya no da segment fault, pero sin embargo me parece que no esta correcto aun, la logica para obtener la mascara al parecer esta mal, pero creo que con los consejos que te doy, podras terminarlo tu solo  #include <cstdlib> #include <cstring> #include <iostream> using namespace std;
char * calcularMascara(int ntipo) { char *mask, *nmask, *punto; mask = new char[16]; // la cadena más grande que podemos tener es 255.255.255.255 más el carácter fin nmask = new char[5]; punto = new char[2];
// manera incorrecta de asignar un valor a un char* o char[], // debes usar strcpy o strncpy //nmask="255."; punto=""; // Lo mas correcto es borrar la memoria antes de que concatenes // de esa manera evitas concatenar con valores basura. // Para borrar de manera rapida la memoria dinamica se usa memset // Aqui para borrar podrias usar tambien strncpy(mask, "", 2); memset(mask, 0, sizeof(char)*16); memset(punto, 0, sizeof(char)*2); strncpy(nmask, "255.", 5); int num = 255; int signed desplaza=0; int unsigned nnum=0; while (ntipo>=0) { strcat(mask,punto); //punto="."; strncpy(punto, ".", 2); if (ntipo>8) { strcat(mask,"255"); ntipo=ntipo-8; } else { desplaza = (8-ntipo); if (desplaza==0 || ntipo==0) { //nmask=(char*)"000"; strncpy(nmask, "000", 4); } else { nnum = ntipo<<desplaza; // Manera incorrecta de convertir un int a char // para eso puedes usar sprintf() (portable) // o itoa() (no portable, pues no es funcion estandard) //nmask = ((char*)nnum); sprintf(nmask, "%d", nnum); } ntipo=ntipo-8; strcat(mask,nmask); // Aquí se la pega } }
// recuerda liberar tu memoria dinamica cuando ya no la necesites. // No libero mask, porque es el puntero que regresa la funcion // pero debes liberarlo afuera. delete nmask; delete punto;
return mask; }
int main() { char *mascara; // Aqui ya no es necesario usar new o malloc pues dentro de la funcion // ya lo estas usando para el puntero que regresas, pero despues de // que lo termines de ocupar liberalo. for (int i = 1; i < 32; i++) { mascara = calcularMascara(i);
printf("%s\n", mascara); delete mascara; }
return 0; }
Saludos y
171
« en: Sábado 23 de Julio de 2011, 15:55 »
Hola MindEye, bienvenido al foro  Deberias publicar tu codigo, para ver que estas haciendo mal, porque asi es como estar adivinando  Aun asi, de manera rapida y por lo que menciones, el error de Violacion de semento (segment fault) ocurre cuando sobreescribes la memoria, esto ocurre por un mal manejo de punteros, y/o arrays. Probablemente al concatenar el arreglo, estas usando un arreglo que no tiene el tamaño suficiente para guardar tu cadena concatenada, entonces como no tiene el tamaño suficiente, se sobreescribe la memoriia y viene el segment fault. Una direccion IP, que ocupe todo sus digitos como la siguiente: 255.255.255.255, tiene una longitud de 15 caracteres (incluyendo los puntos), por lo tanto, debes definir un arreglo con un tamaño minimo de 16, ya que ademas, las cadenas requieren espacio para un caracter adicional, puesto que todas llevan el caracter nulo '\0' para indicar el final de la cadena. Por lo tanto al definir tu variable para la direccion IP si utilizas arreglos quedaria asi: char direccion_ip[16];
Si utilizas memoria dinamica y punteros: char *direccion_ip = (char*) malloc(sizeof(char)*16);
Si eso no corrige tu codigo, publica lo que haces para ver donde esta el error. Saludos
172
« en: Sábado 23 de Julio de 2011, 08:27 »
Yo tengo la idea, tengo el codigo...
Y donde esta el codigo? yo al menos no lo veo, no lo has publicado. Ya te dije antes que si lo tienes y no te da lo que desees, lo publiques, y aqui te podemos ir ayudando entre todos, pero llevas dos mensajes y por mi parte no veo nada. Bueno, veremos si es cierto, te dare mas pistas a ver si con eso lo resuelves. IndexOf te regresa la posicion de la cadena especificada, en la instancia de la cadena actual, si no se encuentra la cadena, regresa el valor -1, cuando te regrese un valor diferente de -1, significa que encontro la subcadena, entonces incrementaras un contador para contar las ocurrencias de la subcadena, y despues utilizaras el metodo SubString(), con el que vas a ir recortando la cadena original, en base al indice que obtuviste con IndexOf, y eliminando desde el principo de la cadena, hasta el indice + el tamaño de la subcadena (esto para eliminar la parte de la frase en donde ya buscaste), todo esto debies hacerlo dentr de un ciclo, deberas detener el ciclo cuando no encuentrea la subcadena, es decir cuando IndexOf te regrese -1.
173
« en: Sábado 23 de Julio de 2011, 07:46 »
Me podrias explicar ( si no es mucha molestia) un poco por favor que es lo que va haciendo el codigo
Eso ya lo hice arriba  , solo tienes que revisar el programa... Bueno, para que te quede mas claro, el algoritmo original imprime el valor de j % 10 (modulo de la division entre 10) y el problema pide que se imprima el valor de j % 10 en caso que sea divisible entre n. Un numero es divisible entre n, si su modulo (residuo) es cero por lo tanto para comprobar que j % 10 es divisible entre n, la condicion es (j % 10) % n == 0. Pero como el ejercicio pide usar "continue" y continue lo que hace es saltar al final del ciclo for, si pusieras la condicion de arriba, se saltaria el ciclo y no imprimiria cuando el valor sea divisibke entre n. Y nosotros queremos en realidad que imprima cuando sea divisble entre n y salte cuando NO sea divisible entre n (o sea, lo contrario) Por lo tanto, la condicion debe ser "lo contrario", es decir, negacion, por eso la condicion debe ser (j % 10) % n != 0. Si aun tienes mas dudas, has una corrida de escritorio, o utiliza la ejecucion paso a paso (F10/F11) de Visual C++ o del entorno de programacion que utilices. Saludos
174
« en: Sábado 23 de Julio de 2011, 05:34 »
La verdad ese algoritmo esta muy enredado, casi no se entiende el objetivo del mismo, es todo un acertijo matematico  Bueno, trate de seguir el enunciado del problema original, si lo entendi bien, es dividir el numero que obtenias en el algoritmo original (j%10), entre un numero n dado (o sea (j&10)%n). Haciendo la modificacion, y siguiendo la premisa de usar continue, obtuve el siguiente codigo, que utilizando el valor de prueba 3, me da una secuencia muy parecida a la que deberias obtener, asi que por eso publico el codigo, sin embargo solo es parecida, ya que la secuencia que obtengo con el valor 3 es la siguiente: 3 33 66 696 690096 90309 903309 90366309 Si observas, la secuencia difiere en los ultimos 3 numeros. Quizas copiaste mal la secuencia, y la secuencia correcta es la que estoy publicando  En todo caso, si no es esa la respuesta, me rindo, porque como dije antes es todo un enigma  #include <iostream> using namespace std;
int main() { int filas = 9; int i; int j; int n; cout <<"Introduzca el numero deseado: \n"; cin >> n; for(i = 1; i <= filas; i++) { if (i % n == 0) cout<<i; for(j = i + 1; j <= (2 * i - 1); j++) { if ((j % 10) % n != 0) continue; cout << j%10; } for(j=j-2; j >= i; j--) { if ((j % 10) % n != 0) continue; cout << j%10; } cout << endl; } }
Saludos
175
« en: Viernes 22 de Julio de 2011, 15:34 »
No se a que te refieres con un "triangulo divisorio". Si fueras un poco mas especifico respecto a cual deberia ser el resultado del programa, te podriamos orientar mejor. Saludos
Páginas: 1 ... 5 6 [7] 8 9 ... 32
|
|
|