Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Escribir archivos grandes

Iniciado por Antares, 10 de Diciembre de 2002, 08:39:52 PM

« anterior - próximo »

Antares

                                Tengo un control CRichEditCtrl y quiero guardar en disco su contenido

¿Que tengo que hacer si supera los 65025 caracteres?

Lo que intente es esto:

 unsigned long Tam;

 Tam=m_CtrlVistaTexto.GetTextLength();

 LPTSTR Texto;

 m_CtrlVistaTexto.GetWindowText(Texto,Tam);

 Arch.Write(Texto,Tam);

 Arch.Close();



Pero resulta q la funcion Write de CFile solo acepta como segundo parametro un UINT

Y si pruebo a escribirlo a trozos no me deja hacer esto: Arch.Write(Texto,1) Para asi poder escribir caracter a caracter.

Y ya de paso; si sabeis algun tutorial del CRichEditCtrl bienvenida sea la URL :)

Asias de antemano

Antares                                

MChiz

                                Hola!
Lo primero... el limite de un UINT es de 4000 millones, creo, no de 65000.
Sobre la funcion Write, no la conozco pero prueba esto:

Write( &texto[ i ], 1 );

Te pide una direccion, y tu no se la estas dando.
Espero que te ayude!
Adios!                                

Antares

                                Aunque no lo he podido probar creo q tienes razon en lo de direccionar, crei q como ya era un puntero bastaba.

Tenia entendido que UINT era unsigned int, o sea 2 bytes, 65000.

No encuentro manera de conseguir todo el texto. La unica forma que veo es leerlo y escribirlo linea a linea. Algo asi.



 int NumLineas,TamLinea,Linea,LongMaxLinea=32000;

 LPTSTR pTexto;



 NumLineas=m_CtrlVistaTexto.GetLineCount();

 for(Linea=0;Linea<=NumLineas;Linea++)

 {

  TamLinea=m_CtrlVistaTexto.GetLine(Linea,pTexto,LongMaxLinea);

  Arch.Write(&pTexto,TamLinea);

 }

 



Compila sin problemas pero al ejecutar la linea del GetLine me da un error de    Unhandle Exception   Creo que es por que LPTSTR esta mal referenciada o mal iniciada y esq no encuentro info sobre LPTSTR.

En la MSDN la referencia a GetLine viene asi:
Citar
CRichEditCtrl::GetLine
int GetLine( int nIndex, LPTSTR lpszBuffer ) const;

int GetLine( int nIndex, LPTSTR lpszBuffer, int nMaxLength ) const;

Return Value

The number of characters copied into lpszBuffer.

Parameters

nIndex

Zero-based index of the line to retrieve.

lpszBuffer

Points to the buffer to receive the text. The first word of the buffer must specify the maximum number of bytes that can be copied into the buffer.

nMaxLength

Maximum number of characters that can be copied into lpszBuffer. The second form of GetLine places this value into the first word of the buffer specified by lpszBuffer.

Remarks

Call this function to retrieve a line of text from this CRichEditCtrl object. The copied line does not contain a terminating null character.

Note   Because the first word of the buffer stores the number of characters to be copied, make sure that your buffer is at least 4 bytes long.
1 ¿Como me aseguro de que mi buffer tiene 4 bytes?
2 ¿Que significa la constante 'const' que pone antes del final ';' de la funcion?
3 ¿Donde esta la info de LPTSTR en la MSDN?
4 Y como no; ¿donde esta el fallo?

Ayuda plis

El novato de Antares                                

fiero

                                Hola,

LPTSTR es un puntero a una cadena de caracteres, o sea *char.

Hay cosas que no vienen en las MSDN, pero que puedes buscar dandole al botón derecho del ratón encima de la palabra en cuestión (en el código) y seleccionando Go To Definition Of .... Si tienes activado "Generate Browse Info" en Proyect->Setings->C/C++, te aparecerá el fichero donde está definida la palabreja, con lo que podrás averiguar qué tipo de dato es.

En cuanto a la llamada a GetLine, tienes que pasarle un puntero a una cadena de caracteres. Esa cadena de caracteres es la que recibirá la linea. Sin embargo tú le pasas un puntero sin inicializar, o sea, sin espacio reservado (aunque le dices a la función que tiene 32000 bytes para poner los datos), por eso es normal que de errores. También para que un bucle for se repita N veces, si empiezas en el 0, debes poner


     int NumLineas,TamLinea,Linea,LongMaxLinea=32000;

     char pTexto[32000];



     NumLineas=m_CtrlVistaTexto.GetLineCount();

     for(Linea=0;Linea<NumLineas;Linea++)

     {

        TamLinea=m_CtrlVistaTexto.GetLine(Linea,pTexto,LongMaxLinea);

        Arch.Write(pTexto,TamLinea);

     }



tambien podrias hacer esto, que es lo mismo:



     int NumLineas,TamLinea,Linea,LongMaxLinea=32000;

     char *pTexto;

     pTexto=new char[LongMaxLinea];



     NumLineas=m_CtrlVistaTexto.GetLineCount();

     for(Linea=0;Linea<NumLineas;Linea++)

     {

        TamLinea=m_CtrlVistaTexto.GetLine(Linea,pTexto,LongMaxLinea);

        Arch.Write(pTexto,TamLinea);

     }

     delete pTexto;



De todas formas, no necesitas escribir en el fichero línea a línea, ya que como dijo MChiz, un entero en windows tiene 32 Bits (4 bytes), o sea, que puedes escribir 4 Gigas de golpe. Seguro que te confundes con MSDOS y con el Borland, que un entero era de 16 bits, pero aquello ya pasó  :ojo:

un saludo                                
www.videopanoramas.com Videopanoramas 3D player

Antares

                                Ya esta solucionado: He sido prudente y he esperado unos dias teniendolo a prueba creo q ya funciona bien he remplazado 20000 palabras en un archivo de 17 Mg le cuesta lo suyo pero son 20000 palabras en 17 Gigas:P

Sabiendo q puedo escribir cuatro gigas, lo dificil me fue conseguir el texto entero en un puntero pq con GetDlgItemText solo pillaba 32000 un SHORT... asi q la unica manera que conozco de conseguir todo el texto del control CRichEditCtrl es seleccionandolo y usando GetSelText si alguien conoce una manera no tan chapucera encantado de atenderle :P aunque la verdad casi no se nota restaurando la seleccion anterior y la primera linea a la vista.

Respecto a lo de los limites al fin encontre la pag q tanto deseaba se titula   C Integer Limits  

Asi q un short es lo mismo que en msdos un int pero el long no ha aumentado sino q queda ahora igual que el int.
El uint 4.294.967.295 uf ¡Que guay! :)

No veo ninguna diferencia entre el int y el long.

Enga... y gracias por vuestra ayuda, por sacarme de ese tremendo error


Y para que quede constancia esto es lo que he hecho:



void CReempView::OnGuardar()

{

CFile Arch;

if(Arch.Open(RutaCompleta,CFile::modeWrite))//CFile::modeCreate |

{



 UINT TamArch,PrimLineaMem,PrimLinea,Dif;

 //Declaramos un puntero a una cadena de texto y la inicializamos con el tamaño del archivo;

 TamArch=m_CtrlVistaTexto.GetTextLength();

 char *pTexto;

 pTexto=new char[TamArch+1];//es lo mismo que  char pTexto[TamArch];

 pTexto[TamArch+1]=0;//Metemos el caracter de fin de cadena



 CHARRANGE RangoMem;//Creamos una estructura donde metera el inicio y fin de la seleccion actual

 m_CtrlVistaTexto.GetSel(RangoMem);//Guardamos la seleccion actual o posicion del cursor en RangoMem



 PrimLineaMem=m_CtrlVistaTexto.GetFirstVisibleLine();

 //LineaCurso=m_CtrlVistaTexto.LineFromChar(-1);

 CHARRANGE Rango;//Creamos otra estructura para indicarle lo que queremos seleccionar

 Rango.cpMin=0;

 Rango.cpMax=-1;//TamArch;//Si ponemos -1 selecciona todo el texto

 

 //Obtenemos el texto seleccionandolo y luego volvemos la vista y la seleccion anterior

 m_CtrlVistaTexto.HideSelection(true,true);

 m_CtrlVistaTexto.SetSel(Rango);

 m_CtrlVistaTexto.GetSelText(pTexto);

 m_CtrlVistaTexto.HideSelection(false,false);

 m_CtrlVistaTexto.SetSel(RangoMem);

 PrimLinea=m_CtrlVistaTexto.GetFirstVisibleLine();

 Dif=PrimLineaMem-PrimLinea;

 m_CtrlVistaTexto.LineScroll(Dif,NULL);

 

 //Lo escribimos

 Arch.Write(pTexto,TamArch);

 

 Arch.SetLength(TamArch);

 Arch.Close();

 m_CtrlVistaTexto.SetModify(false);

 Cambios=false;

 Cancel=false;

 //delete pTexto;

 //Si intento borrar la variable me da un error DAMAGE: after Nomal block

  }

else if(Cambios==false)

 AfxMessageBox("No se han efectuado cambios",MB_ICONINFORMATION);



else

 AfxMessageBox("No se puede abrir el archivo para guardar",MB_ICONERROR);



}





Antares                                

Mars Attacks

                                Hey, eso podría servir como un buen code of the week ;)                                

Antares

                                Enserioooooo

:oops:

Que es lo que te ha gustado. ¿"La trampa" de seleccionar para conseguir el texto?

O lo dices solo por el volumen?

Antares :P                                

Mars Attacks

                                El código en sí, que puede resultar instructivo para otros que tengan el mismo problema :)                                






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.