ayuda con parametro a funcion open()

Iniciado por luzzzifer, 24 Agosto 2010, 02:15 AM

0 Miembros y 2 Visitantes están viendo este tema.

luzzzifer

Hola a todos:
     Ante todo buen día, hoy traigo una duda que quisiera que me la despejen,  ;D , resulta que estoy programando una función en C que reciba ficheros a través de una socket TCP para Windows XP SP2, y estoy utilizando la clase fstream:

unsigned long Recvfile(int *dsock, char buffer[255])//dsock puntero al socket creado
{
std::string cadena;

char bytes[1024],*a=getenv("SystemDrive"), dir[20]={0};

int len=0,i, llega=0;

std::ofstream archivo;

for(i=0 ; i<=255 ; i++)          //Esto lo que hace es quitar el caracter "!" del
{                                          //principio del array buffer es decir
bytes[i]=buffer[i+1];       //buffer="!100#nombre"  ,  quedaria
if(buffer[i]==0){break;}  //bytes="100#nombre"
}                                            //(no se me ocurrio otra forma de hacerlo)
                                                      //luego bytes se reutilizaria para almacenar los
                                                     //datos que llegan (corregirme si este modo no
                                                     //es correcto..)

cadena=Split(bytes, '#', 0);

i=atoi(cadena.c_str());  //esta variable i contendra el tamaño del archivo que llegara

        cadena=Split(bytes, '#', 1);

strcat(dir,a);
// dir[2]='\\';

        strcat(dir,cadena.c_str());

archivo.open(dir,std::ios::binary);

while(llega!=i)
{

// if(len==-1){Desconexion(*dsock);break;}  la funcion Desconexion no viene al caso

len=recv(*dsock, bytes, sizeof(bytes), 0);

llega+=len;

archivo.write(bytes, len);

}

archivo.close();

return llega;
}

//Esta es la funcion Split para que la vean por las dudas que tenga errores

std::string Split(std::string buffer, char caracter, int parte)
{
std::string cad1, cad2;
int i;
i=buffer.find(caracter);

cad1=buffer.substr(0,i);
cad2=buffer.substr(i+1,buffer.length());

if(parte==0){return cad1.c_str();}else{return cad2.c_str();}
}




       Bueno como verán la idea es que se cree en el disco donde está instalado el sistema operativo. Bien, el problema esta en el primer parámeto que le paso a .open(), que sería el path del archivo a crear, no se cómo hacer para que la función me acepte el path que le estoy pasando con la variable dir, he probado de otras formas tmb, con punteros o con las clase string haciendo un .c_str() pero no hay caso, la única forma en la que anda y envía ficheros sin problemas es cuando le paso el parámetro a mano, es decir "C:\\fichero.exe" por ej, lo que no me sirve.
     
      Además, del otro lado (el programa que envía) tengo el mismo problema, sólo me abre el archivo cuando se la paso a mano y nunca pude lograrlo con una variable. El código siempre compila bien, sin errores pero no funciona y la función me pide un const char *, intenté varias veces ya pero me he quedado trabado ahi...

     Desde ya muchas gracias y cualquier corrección-crítica constructiva que tengan para hacerme la aceptaré como es debido ya que si se puede mejorar u optimizar código adelante!...

Littlehorse

Depura los valores que contienen las cadenas para ver el porque falla, por lo pronto concatenas el contenido de 'cadena' solo con una unidad de disco (X:) por lo tanto la ruta resultante sera incorrecta.
Luego de eso, deberias revisar si open establece failbit en la apertura del archivo.

Por lo pronto solo eso, luego lo miro mejor y te aviso si encuentro algo mas.

Saludos

An expert is a man who has made all the mistakes which can be made, in a very narrow field.

luzzzifer

#2
Hola LittleHorse:
    Muchas gracias por la antencion, hago un breve explicacion de la variable dir, esta primero le asigno el disco (C: o D: etc), después, a eso, le concateno con strcat() el nombre del fichero junto con la barra invertida, ej "\fichero.jpg". Ese contenido estaría en la variable cadena, cuyo contenido varía dos veces, primero le asigno el tamaño( cadena=Split(bytes, '#', 0); )y después le asigno el nombre del fichero( cadena=Split(bytes, '#', 1); ). Ese último valor se lo concateno a dir. Por lo que quedaría "X:\fichero.jpg".
   
    Estuve buscando algo referido con failbit ya que no sabía de que se trataba, e hice la prueba con badbit y lo establece a 0, failbit 1, lo que quiere decir que un error sobre la cadena ha ocurrido.
    Para mi, despues de concatenar 2 veces sobre dir, la función no ve esa variable como una cadena. Probé con declarar una variable e inicializarla inline ( char[25] path="C:\\fichero.jpg") y a eso si me lo toma, pero cuando quiero armar "a mano" esa cadena no funciona.

     He hecho la prueba de utilizar un bucle para imprimir el contenido de dir ya concatenado y el de path, que es inicializado inline, y en el elemento final de path me marca como que tiene guardado el contenido 'S' .... ?¿? ...cosa que con dir no pasa... será de String?¿  ;D.

     También hice la burrada de agregarle al final del array dir la 'S' a mano y obvio que no funcionó jeje... y es una lástima porque todos los ejemplos que encuentro por internet utilizar a .open("C:\\fichero"...), es decir nadie le pasa como parámetro una variable como es mi caso.

Muchas gracias por la atención....Saludoss!!

Littlehorse

#3
En el código inicial la única barra invertida es una asignación que esta comentada, por eso te dije antes lo de la ruta incorrecta.

Igualmente solucionado eso, debería funcionar perfectamente tanto con una cadena literal o con una cadena a medida. En este caso el parámetro que acepta la función es siempre el mismo sin importar cuantas veces modifiques la cadena.

Si vos verificas el contenido de dir justo antes de pasarla como parámetro a open, el contenido es correcto o no? si es incorrecto entonces esta claro que el problema pasa por el procesamiento que le realizas a la cadena.

El problema principal es que el valor de retorno de la función Split es temporal y este puede ser invalidado en las llamadas siguientes a esa función. La variable cad1 y cad2 son locales a la función, y permanecen mientras se encuentren en el ámbito de la función correspondiente, lo mismo ocurre por supuesto con el puntero que devuelve c_str, en este caso este ultimo existe temporalmente en el stack.
Intenta devolviendo directamente el string.

Saludos
An expert is a man who has made all the mistakes which can be made, in a very narrow field.

luzzzifer

Hola a todos:
       Estoy contento, he logrado solucionar el inconveniente y lo contaré para que no se topen con el mismo problema.
       Lo que hice fue sobreescribir el cero de cadena, osea el caracter nulo de la variable dir, una vez que la terminé de armar con las dos concatenaciones. Antes también había probado con lo mismo, pero le asigné el cero en un elemento del array equivocado, probé millones de cosas y esa ya la había descartado, hasta que lo repetí y salió, además, yo daba por hecho que se encontraba ese caracter nulo al final de los caracteres, es decir que si el array dir tiene 20 dimensiones y sólo le asignamos "hola", hay que aplicar dir[5]=0;    y eso también se logra asiendo dir[strlen(dir)-1]=0;    como es en mi caso, en el que no sé hasta qué dimensión habrá caracteres.

       Bueno hemos aprendido que cuando armamos "a mano" una cadena concatenando otras, debemos sobreescribir el caracter nulo..   :laugh: :laugh::laugh:

       Muchas gracias LittleHorse por la atención y por los planteos que me realizaste ;-)   Saludos!!!

Littlehorse

Dudo que ese haya sido el error porque strcat agrega el carácter nulo a la cadena resultante. En todo caso lo que tenes que asegurarte es que ambas cadenas estén terminadas en NULL a la hora de la concatenación.

Citarchar * strcat ( char * destination, const char * source );

Concatenate strings
Appends a copy of the source string to the destination string. The terminating null character in destination is overwritten by the first character of source, and a new null-character is appended at the end of the new string formed by the concatenation of both in destination.

Igualmente revisa lo que te dije antes del valor de retorno de Split. Me alegro que lo hayas solucionado.

Saludos
An expert is a man who has made all the mistakes which can be made, in a very narrow field.