Una observación, la función
fgets() es más segura por cuánto permite limitar la longitud de la cadena recibida (el argumento MAX que le pasas), y así prevenir un desbordamiento del búfer. Una verificación que no hacen ni
gets() ni
scanf(). De hecho, algunos compiladores advierten sobre el uso riesgoso de
gets() , desaconsejando su uso.
Yo en su lugar seguiría usando
fgets() pero "recortaría" la cadena:
if ( ( len = strlen( nombre ) ) > 0 && nombre[len - 1] = '\n') nombre[len - 1] = '\0';
Ahora, respecto a que quieres pasar el nombre del archivo sin distinguir mayúsculas y minúsculas lo veo un poco más difícil. Obviamente, no te vas a poner a probar todas las combinaciones de minúsculas y mayúsculas, a ver si alguna abre el archivo (jeje)
A mi se me ocurre listar el contenido del directorio, y probar nombre por nombre contra el nombre dado por el usuario. Si alguno coincide (despreciando mayúsculas y minúsculas), abrir el fichero. Para eso, se requiere un compilador que implemente la biblioteca
<unistd.h> la cual obedece un estándar llamado POSIX. Es hecho que sea estándar significa que con seguridad la tienes en una implementación de C para Linux, pero no necesariamente en Windows
(ya saben como es Microsoft, rompe-estándares).
¿Usas Windows verdad? En ese caso, compila con IDE libre para Windows como Dev-Cpp, o MinGW con gcc/g++. No estoy seguro que Borland C lo soporte (la verdad no tengo idea, pues no uso ni Windows ni Borland, jeje).
Bueno, a lo nuestro.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <ctype.h>
#define MAX 40
char * str_to_lower( char *);
int main()
{
FILE *fd = NULL;
char name[MAX];
unsigned long len;
char ready;
char dir_name[100]; /* nombre de directorio */
DIR * dir_ptr = NULL; /* apuntador a directorio */
struct dirent * dirent_ptr; /* estructura 'directory-entry' */
char * f_name; /* name de cada fichero leído en el directorio */
printf("Que archivo quieres abrir: ");
fgets( name, MAX, stdin );
/* quitamos el '\n' al final de la cadena */
if ( ( len = strlen( name ) ) > 0 && name[len - 1] == '\n' )
name[len - 1] = '\0';
strcat( name, ".txt" ); /* añadimos '.txt' al final */
/* pongamos el directorio como el actual, puedes cambiarlo xD */
strcpy( dir_name, ".");
/* 'abrimos' el directorio para leer su contenido */
if ( ( dir_ptr = opendir( dir_name ) ) == NULL ) {
printf( "No existe o no se pudo abrir el directorio '%s'\n", dir_name );
return -1;
}
/* ahora recorremos todo el directorio, buscando
* names de fichero que coincidan */
ready = 0;
while ( ( dirent_ptr = readdir( dir_ptr ) ) != NULL ) {
f_name = dirent_ptr -> d_name;
/* verificamos omitiendo mayúsculas y minúsculas */
if ( ! strcmp( str_to_lower(name), str_to_lower(f_name) ) )
if((fd = fopen(f_name, "r")) != NULL) {
printf("Se abrio '%s'\n", f_name);
ready = 1;
}
}
/* y si al finalizar el ciclo no encontro, emitir error */
if ( !ready )
printf("No se pudo abrir el archivo\n");
/* cerramos el directorio, y el fichero */
if ( dir_ptr != NULL ) closedir( dir_ptr );
if ( fd != NULL ) fclose( fd );
return 0;
}
/* Pasa todos los caracteres de la cadena a minúsculas */
char * str_to_lower( char * s ) {
size_t k = 0;
while ( s[k] != '\0' ) {
if ( isalpha( s[k] ) ) s[k] = tolower( s[k] );
k++;
}
return s;
}
Este programa es funcional, sólo necesita ser compilado y probado. Por ejemplo, yo tengo el mi directorio un file1.txt, y al pasarle el nombre 'FiLe1' me dice que lo abrió. Al pasarle 'FilE2' no lo abre, porque no tengo 'file2.txt'.
Como ves, recorremos todo el directorio y convertimos sus nombres a minúsculas usando las funciones de biblioteca
isaplha() (prueba si es una letra), y
tolower() (pasa una letra a minúscula).
Lo de recorrer directorio requiere conocer acerca de la estructura
dirent y la función
readdir. Yo escribí un post al respecto el otro foro, te invito a leerlo para comprender esto mejor:
http://foro.chuidiang.com/ccplusplus-linux/listar-contenido-de-un-directorio-usando-funciones-posix-de-c/Se esperan comentarios, opiniones, etc .....