Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: MasterPunk en 26 Enero 2012, 16:06 pm



Título: comprobar si existe un archivo
Publicado por: MasterPunk en 26 Enero 2012, 16:06 pm
Hola, esto deberia devolver true si existe el archivo, y false si no existe, pero siempre devuelve true, ¿por que?

Código
  1. bool existe(){
  2.    fstream ok;
  3.    char texto[200];
  4.    ok.open("C:\\thanks.txt", ios::in); // Comprueba si existe thanks.txt
  5.    ok >> texto; // Leo una primera linea
  6.    if (!ok.eof()){
  7.        ok.close();
  8.        return false;
  9.    }
  10.    else{
  11.        ok.close();
  12.        return true;
  13.    }
  14. }

Código:
127 C:\Users\*\Desktop\*\main.cpp [Warning] the address of `bool existe()', will always evaluate as `true' 

EDITO: funciona perfectamente, el problema estaba al llamar a la funcion.
disculpad las molestias


Título: Re: comprobar si existe un archivo
Publicado por: Xandrete en 26 Enero 2012, 17:50 pm

Hace un tiempo escribí sobre una manera (no portable, pues sólo funcionaría en sistemas Unix) de llevar algo así acabo. Te pongo el link (para que veas el contexto) y el código (es una función).

http://foro.elhacker.net/empty-t350434.0.html (http://foro.elhacker.net/empty-t350434.0.html)

Código
  1. int existsFile(char* filename) {
  2. FILE* f = NULL;
  3. f = fopen(filename,"r");
  4. if (f == NULL && errno == ENOENT)
  5. return 0;
  6. else {
  7. fclose(f);
  8. return 1;
  9. }
  10. }

Como puedes comprobar, originalmente era una función para C (si quieres, puedes usarla en C++ tal cual o adaptarla como más te convenga). Se incluye previamente la librería errno.h, que no tiene definidos los mismos códigos de error en Unix y en Windows (ENOENT corresponde al error genérico "No such file or directory", que si no me equivoco, no está definido en Windows). Si quisieras hacer algo parecido en Windows, tendrás que incorporar alguna librería propia de ese S.O. (es posible que haya una manera portable de hacer esto, pero ahora mismo estoy enfermo y no puedo pensar con mucha claridad, así que cedo el testigo a otra persona >_<).

Saludos, jefe.

EDITO: No leí tu edito >.<, lo siento


Título: Re: comprobar si existe un archivo
Publicado por: x64core en 26 Enero 2012, 19:05 pm
si es en W$ porque no usar simplemente la api FileExist


Título: Re: comprobar si existe un archivo
Publicado por: MasterPunk en 26 Enero 2012, 21:40 pm
Uso windows.

si es en W$ porque no usar simplemente la api FileExist

Pues porque me acabo de enterar de que existe jajaja
Y a google no le apetece decirme como se usa.


Título: Re: comprobar si existe un archivo
Publicado por: x64core en 26 Enero 2012, 21:56 pm
perdon yo me equivoque LOL
no existe una api asi, tenia una funcion que se llamaba asi xd

#include <fstream>

inline bool FileExists(const char * filename)
{
  return std::ifstream(filename);
}

int main()
{
   bool j = FileExists("F:\\Windows\\Notepad.exe");
return 0;
}


creo que con la api getAttr se puede hacer tambien


Título: Re: comprobar si existe un archivo
Publicado por: BlackZeroX en 27 Enero 2012, 00:28 am
De hecho puedes hacerlo con el api: GetFileAttributes http://msdn.microsoft.com/en-us/library/windows/desktop/aa364944%28v=vs.85%29.aspx, si te retorna 0 es que no existe...


Título: Re: comprobar si existe un archivo
Publicado por: Foxy Rider en 27 Enero 2012, 22:16 pm
¿Y por qué no simplemente fopen()? es simple, es estándar y es portable.
naturalmente hay que olvidarse de errno, pero si un simple fopen pidiendo acceso de lectura no retorna un descriptor, entonces es claro que ese fichero está fuera del alcance (exista o no) y se puede dar un mensaje de que el fichero no existe o no tiene los permisos apropiados.

Saludos.

P.S → Guarda con usar inline, si llamás la función muchas veces, pero la usás poco (en un bucle, por ejemplo) está bien usarlo por que se "expande" el código una vez, ahora ... si la usás de forma dispersa lo mejor es evitar inline, por que causa que el binario engorde con código duplicado.
Depende del compilador igual si obedece inline, lo toma como una sugerencia, o si optimiza esos casos de código duplicado.

P.S 2 →  PEEERO, en este caso, consume más tiempo hacer la operación de I/O al acceder al disco duro (que, tiene una linda latencia si no es un SSD) que lo que te ahorrás en el par de instrucciones assembly de llamar una función abriendo una instancia en el stack y demás, así que aunque usases la función en un for, lo que ganás es siquiera medible.



Título: Re: comprobar si existe un archivo
Publicado por: Xandrete en 30 Enero 2012, 20:42 pm
¿Y por qué no simplemente fopen()? es simple, es estándar y es portable.
naturalmente hay que olvidarse de errno, pero si un simple fopen pidiendo acceso de lectura no retorna un descriptor, entonces es claro que ese fichero está fuera del alcance (exista o no) y se puede dar un mensaje de que el fichero no existe o no tiene los permisos apropiados.

Saludos.

P.S → Guarda con usar inline, si llamás la función muchas veces, pero la usás poco (en un bucle, por ejemplo) está bien usarlo por que se "expande" el código una vez, ahora ... si la usás de forma dispersa lo mejor es evitar inline, por que causa que el binario engorde con código duplicado.
Depende del compilador igual si obedece inline, lo toma como una sugerencia, o si optimiza esos casos de código duplicado.

P.S 2 →  PEEERO, en este caso, consume más tiempo hacer la operación de I/O al acceder al disco duro (que, tiene una linda latencia si no es un SSD) que lo que te ahorrás en el par de instrucciones assembly de llamar una función abriendo una instancia en el stack y demás, así que aunque usases la función en un for, lo que ganás es siquiera medible.



¡Hola!

Si, claro. Si no puedes abrir el archivo y no te hace falta saber exactamente el motivo, ya va bien así (yo hacía lo propio con el open cuando me devolvía -1). Pero cuando quieres saber que no puedes abrir el archivo porque éste no existe y sólo porque éste no existe, tienes que recurrir a otros medios.

¡Saludos!


Título: Re: comprobar si existe un archivo
Publicado por: burbu_1 en 30 Enero 2012, 23:43 pm
puedes usar el api FindFirstFile, y si el archivo no existe GetLastError devuelve ERROR_FILE_NOT_FOUND.


Título: Re: comprobar si existe un archivo
Publicado por: wachi en 4 Febrero 2012, 04:19 am
si,puedes usar FindFirstFile, por supuesto acompañada de FindNextFile.....
a mi en lo personal me gustan mucho estas ,también si usas c++builder la vcl.h tiene una funcion llamada FileExists() que te permite saber si un archivo existe ....

saludos....
 


Título: Re: comprobar si existe un archivo
Publicado por: naderST en 4 Febrero 2012, 15:53 pm
Estoy de acuerdo con [Alex] por qué perder la portabilidad usando el API de Windows si puedes usar fopen y ver si este retorna NULL, o bien si tiene que ser en C++ puedes hacerlo así:

Código
  1. bool file_exists(const char * f){
  2.    ifstream file;
  3.    file.open(f);
  4.    if(file.fail())
  5.        return false;
  6.    file.close();
  7.    return true;
  8. }
  9.  


Título: Re: comprobar si existe un archivo
Publicado por: wachi en 4 Febrero 2012, 18:04 pm
estoy  de acuerdo contigo [naderST] ,esa también es una buena opción ....muy bueno ejemplo...

saludos...


Título: Re: comprobar si existe un archivo
Publicado por: Miseryk en 8 Febrero 2012, 20:18 pm
La mejor manera y para no abrir handles y demas, creo q es esta.

Código
  1. bool FileExist2(const char * filename)
  2. {
  3. return GetFileAttributes(filename) != 0xFFFFFFFF;
  4. }
  5.  


Título: Re: comprobar si existe un archivo
Publicado por: wachi en 9 Febrero 2012, 04:04 am
hola...
Miseryk esa forma es buena pero ,como dijeron antes aquí ,no es necesario el uso de  apis de windows ,ya que estas hacen que se pierde la portabilidad....

saludos....