Menú

Mostrar Mensajes

Esta sección te permite ver todos los mensajes escritos por este usuario. Ten en cuenta que sólo puedes ver los mensajes escritos en zonas a las que tienes acceso en este momento.

Mostrar Mensajes Menú

Mensajes - amchacon

#231
Programación C/C++ / Re: dudas con strcpy
15 Marzo 2014, 22:40 PM
Cita de: yoel_alejandro en 15 Marzo 2014, 21:44 PM
En el caso que plantea leosansan, supongo que dependerá del compilador. Probablemente cualquier compilador moderno tomará previsiones adecuadas si la cadena de origen excede en longitud a la cadena de destino.
Eso no es así, ya se lo desmentí a Leosan.

Hacer esas aproximaciones suele dar muy malos resultados. Luego ocurren los errores extraños y inexplicables, los crasheos aleatorios...

Como regla general, siempre hay que ceñirse a lo que te diga el creador de la función. Cualquier truco o atajo que intentes no está garantizado contra errores y probablemente acabe muy mal.

Cita de: yoel_alejandro en 15 Marzo 2014, 21:44 PMEstas dificultades se evitan cómodamente usando la clase string de C++. Pero personalmente creo que quién se quiera formar como un verdadero programador debería pasar primero por C (con todas sus dificultades asociadas), y luego ir a C++. Hay que "ensuciarse" primero para aprender bien. Bueno, al menos es mi criterio, no se qué opinen los demás (?)
Un buen programador es el que es capaz de escribir la solución de un problema paso a paso. El usar un lenguaje u otro solo sirve para probar tu solución en una computadora.

Lo que si es verdad esque es importante conocer los mecanismos de abstracción (grafos, listas, vectores...). Y una forma práctica de aprenderlo es re-hacer la librería básica del lenguaje.

PD: Un buen programador no tiene problemas en adaptarse de un lenguaje a otro en poco tiempo. Aunque no lo haya visto nunca, normalmente son todos muy parecidos.
#232
Programación C/C++ / Re: dudas con strcpy
15 Marzo 2014, 21:33 PM
Cita de: yoel_alejandro en 15 Marzo 2014, 20:32 PMNOTA. En cuánto a la declaración de string constantes no se con exactitud si la forma de interpretar la sentencia depende del compilador o de la versión de C, o de si es en C ó en C++. Que alguno de los usuarios más versados en el tema por favor nos complemente.
Te refieres a:
Código (cpp) [Seleccionar]
char *cadena = "hola mundo";

En ningún compilador de C/C++ podrás modificar el contenido de cadena. Más que nada porque lo que estás haciendo es declarar un puntero que apunta a una cadena literal (y los valores literales son constantes por definición).

Excepción los arrays de chars, donde por comodidad sintáctica se te permite escribir esta sentencia:
Código (cpp) [Seleccionar]
char cadena[] = {'h','o','l','a',' ','m','u','n','d','o','\0'};

De esta forma:
Código (cpp) [Seleccionar]
char cadena[] = "hola mundo";

Cita de: leosansan en 15 Marzo 2014, 21:21 PM
Totalmente de acuerdo con ambos. Cito una indicación de la página de
cplusplus :

Sin embargo ..... supongo que es el propio compilador el que lleva a cabo la operación de ampliar el espacio de la cadena receptora, que en principio es de 10 y podría provocar el overflow, pero en la práctica eso no sucede.

Está es la salida al código de ejemplo:


Como pueden observar, str2 "se metió" en la cadena str1 que originalmente erra de dimensión 10 sin problemas.

Eso si, destacar que si str2 no tiene suficiente dimensión quedará en la  cadena original el "resto" de la dicha cadena:


Código (cpp) [Seleccionar]

#include <stdio.h>
#include <string.h>
int main ()
{
   int i;
   char str1[ ]="A ver si cabe la cadena str1 en srt2";
   char str2[10]="leosansan";
   printf ("\nCadena str1 antes del cambio:\n%s",str1);
   printf ("\n\nCadena str2 antes del cambio:\n%s",str2);
   strcpy (str2,str1);
   printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
   printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
   for( i=0;str2[i]; i++)
     printf( "%c",str2[i] );
   printf( "\n\nlongitud de la nueva cadena str2=\n%d", strlen(str2) );
   return 0;
}


Espero no haberme liado con este rollito, ¿o tal vez si?. Ya me contaran ustedes.
Pues si te has liado, prueba este otro código:

Código (cpp) [Seleccionar]
#include <stdio.h>
#include <string.h>

int main ()
{
   int i;
   char str1[ ]="Cosita grande y hermosa";
   char str2[10]="leosansan";

   printf ("\nCadena str1 antes del cambio:\n%s",str1);
   printf ("\n\nCadena str2 antes del cambio:\n%s",str2);
   strcpy (str2,str1);
   printf ("\n\nLo que queda en str1: %s\n\nCopiado, nuevo str2:\n%s\n\n",str1,str2);
   printf("\n\nY la cadena str2 impresa caracter a caracter:\n ");
   for( i=0; str2[i]; i++)
       printf( "%c",str2[i] );
   printf( "\n\nlongitud de la nueva cadena str2=\n%d\n", strlen(str2) );

   return 0;
}


Fijate en el contenido de str1:
Citarnde y hermosa

Ha dado overflow, te has salido del espacio de str2 y estás sobreescribiendo la cadena str1.

¿Por que en el otro ejemplo si funcionaba? Pues porque lo has interpretado mal:
CitarA ver si cabe la cadena str1 en srt2
abe la cadena str1 en srt2

Se ha comido lo que está en negrita, lo que pasa esque no suena raro y lo has pasado por alto sin darte cuenta.
#233
Pero esque las piramides ya las hecho ;D

Pensé en hacer un circulo, pero hacer un circulo en una consola ASCII no es trivial. Para que te quedara bien habría que hacer "anti-alising" con alguna letra más redondita.

Cita de: leosansan en 15 Marzo 2014, 14:29 PMDe todas formas sería más fácil usando una función matemática. ¿Te animas?.[/center]
¿Más fácil? De eso nada xD

Para empezar rompe el enfoque arriba-abajo, además para sacarla tendrías que hacer unas series de fourier muy divertidas... Y probablemente alguna casilla te salga mal ya que no es exacta y las casillas no admiten decimales.
#234
Programación C/C++ / Re: Ayuda con programa
15 Marzo 2014, 16:49 PM
Para eso tienes el cin.get()

Que además es estándar.
#235
Haz lo siguiente, definete esta funcion en la clase:

Código (cpp) [Seleccionar]
void WriteInFile(fstream &file)
{
   file.write((char*)&ID,sizeof(int));
   file<<name<<' ';
   file.write((char*)&num,sizeof(unsigned short));
   file.write((char*)&money,sizeof(double));
}


Y para leer lo mismo pero al reves:

Código (cpp) [Seleccionar]
void ReadInFile(fstream &file)
{
   file.read((char*)&ID,sizeof(int));
   file>>name;
   file.read((char*)&num,sizeof(unsigned short));
   file.read((char*)&money,sizeof(double));
}


Lectura/escritura 100% binaria. Supongo que es lo que querías.
#236
Revisa la clase que hay un método muy interesante:
Código (cpp) [Seleccionar]
void changeName(string Name);
Blanco y en botella. Usa ese método para cambiar el nombre. Problema resuelto.

Código (cpp) [Seleccionar]
fstream file("data.dat",ios::in | ios::out);
item N;
   
string aux;
file>>aux;
   
N.changeName(aux);


CitarPorque no te gusta utilizar reinterpet_cast ?
Transformar objetos a datos primitivos es una barbaridad, definirte operadores de conversión es más seguro y efectivo.
#237
Cita de: patilanz en 15 Marzo 2014, 13:02 PMY lo de string no se puede guardar con una clase porque tiene memoria dinamica ?
Si que se puede, lo que no puedes hacer es escribir en su memoria a lo bruto. Para empezar porque lo que estas haciendo es sobreescribir su puntero (la clase string no guarda el texto, sino el puntero donde tiene reservado el texto).

El encapsulamiento y el que haya métodos privados y públicos se hizo por algo. Si quieres adceder al contenido del string, usa sus métodos, si quieres modificarlo usa sus métodos tambien.

Cita de: patilanz en 15 Marzo 2014, 13:02 PMpero deberia de funcionar con reinterpet_cast. Y lo de string no se puede guardar con una clase porque tiene memoria dinamica ?
No debería, ya no solo por lo que te he dicho antes sino porque le has pasado el objeto entero (que tiene más cosas que la clase string).

Yo soy muy poco partidario de usar un reinterpet_cast para un objeto, lo ideal es definir un operador char* en la clase. Aunque en este ejemplo no lo necesitas (sigue leyendo).

Cita de: patilanz en 15 Marzo 2014, 13:02 PMSi es asi como lo puedo guardar en un archivo?
Crea este método en la clase:
Código (cpp) [Seleccionar]
void setNombre(string &texto)
{
  n = texto;
}


Y lee el nombre con el operador >> que para eso está (o bien, getline si es una línea entera):
Código (cpp) [Seleccionar]
fstream file("data.dat",ios::in | ios::out);
Name N;

string aux;
file>>aux;

N.setNombre(aux);
#238
Programación C/C++ / Re: Ayuda con programa
15 Marzo 2014, 12:14 PM
Que manía tienen los profesores de mezclar C y C++.

Yo cambiaría:
Código (cpp) [Seleccionar]
cout<<"\n";

Por:
Código (cpp) [Seleccionar]
cout<<endl;

Ya que con endl se refresca el flujo de salida además.
#239
Código (cpp) [Seleccionar]
file.seekg(0);
¿Para que pones esto? Por defecto siempre se empieza en la posición cero.

Y en cuanto al error, en un string no puedes escribir directamente. Tienes que llamar a sus métodos/operadores y ellos se encargan de hacer sus gestiones con la memoria dinámica.

Podría funcionar así:

Código (cpp) [Seleccionar]
#include "stdafx.h"
#include <iostream>
#include <fstream>
using namespace std;

class name
{
   char n[1000];
public:
  // name(string N=""):n(N) {}
   char* getName()
   {
       return n;
   }
};

int _tmain(int argc, _TCHAR* argv[])
{
   fstream file("data.dat",ios::in | ios::out | ios::binary);
   name N;
   file.read(N.getName(),1000);
   if(!file.fail())
       cout << "Good!";
   getchar();

   return 0;
}


Aún así me parece una práctica muy poco apropiada y poco práctica.

PD: ¿Que compilador usas? Lo de t_main me llama la atención.
#240
Citar¿Cuál es el motivo de usar otro compilador que no sea Visual Studio si funciona igual?
El único motivo que se me ocurre es para compilarlo en otras plataformas con más comodidad.

Porque para Windows el mejor compilador es el de Microsoft.

PD: Puedes usar el compilador de Microsoft en otro IDE, si no tienes sientes comodo con el IDE de Microsoft.