Foros del Web » Programación para mayores de 30 ;) » C/C++ »

funcion rename

Estas en el tema de funcion rename en el foro de C/C++ en Foros del Web. Hola amigos del foro, estuve probando un poco la funcion rename y lo que obtengo es que la aplicacion solo renombre el archivo siempre y ...
  #1 (permalink)  
Antiguo 24/10/2012, 22:36
 
Fecha de Ingreso: agosto-2012
Mensajes: 17
Antigüedad: 11 años, 8 meses
Puntos: 0
funcion rename

Hola amigos del foro, estuve probando un poco la funcion rename y lo que obtengo es que la aplicacion solo renombre el archivo siempre y cuando esta este en el mismo directorio que el archivo a renombrar mi pregunta es:

se pueden renombrar archivos independientemente de donde este la aplicacion?

Mi idea es hacer un programa para renombrar varios archivos independientemente de donde se instale, creo que se llama el PATH, espero que me puedan ayudar, les dejo lo que tengo hecho hasta ahora, gracias y saludos

Código:
    #include <stdio.h>
     
    int main()
    {
      rename("test.txt", "prueba.txt");
      return 0;
    }
  #2 (permalink)  
Antiguo 25/10/2012, 03:25
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: funcion rename

Cuando indicas una ruta relativa se interpreta como que se debe ejecutar en el directorio de trabajo (current working directory), que se define como el directorio final de la ruta activa.

En el caso que indicas suponiendo que la aplicacion está en C:/mientorno/ solo funcionará con los archivos que estan en ese directorio (p.ej. 'C:/mientorno/test.txt'), si quieres trabajar con otros directorios tienes que: usar los modificadores de directorio (p.ej. el archivo './test.txt' o '../test.txt' estará en 'C:/'; o bien tienes que cambiar la ruta activa (esto depende del s.o., en windows se hace con SetCurrentDirectory); o bien tienes que usar la ruta absoluta del archivo.

Si estan en windows normalmente esto se hace a traves de un dialogo de exploracion de archivos que te retorna una ruta absoluta, y sobre esa ruta haces las operaciones necesarias (duplicas la ruta, una ladejas como ruta original, la otra cambias el nombre antiguo por el nuevo y aplicas la funcion rename)

Saludos
vosk
  #3 (permalink)  
Antiguo 25/10/2012, 03:49
 
Fecha de Ingreso: julio-2012
Mensajes: 133
Antigüedad: 11 años, 9 meses
Puntos: 22
Respuesta: funcion rename

Hola ema1993.

Debes anteponer la ruta al nombre del archivo, en tu ejemplo:
Código C:
Ver original
  1. rename("C:\\Carpeta\\test.txt", "C:\\Carpeta\\prueba.txt");

Un ejemplo simple, supongamos que en C:\Carpeta1, tenes los archivos A1.TXT, A2.TXT, A3.TXT, A4.TXT, A5.TXT . Y deseas renombrar esos archivos como UNO.TXT, DOS.TXT, TRES.TXT, CUATRO.TXT, CINCO.TXT pero en otro destino, digamos C:\Carpeta2:

Código C:
Ver original
  1. #include <stdio.h>
  2. #include <string.h>
  3.  
  4. #define PATH1 "C:\\CARPETA1\\"  /* Ruta origen */
  5. #define PATH2 "C:\\CARPETA2\\"  /* Ruta destino */
  6.  
  7. int main()
  8. {
  9.   char *oldname[5] = {"A1.TXT","A2.TXT","A3.TXT","A4.TXT","A5.TXT" };
  10.   char *newname[5] = {"UNO.TXT","DOS.TXT","TRES.TXT","CUATRO.TXT","CINCO.TXT"};
  11.   char oldn[256], newn[256];
  12.   int i;
  13.  
  14.   for (i = 0; i < 5; i++) {
  15.     /* Ruta1 + nombre_viejo */
  16.     strcpy(oldn, PATH1);
  17.     strcat(oldn, oldname[i]);
  18.     /* Ruta2 + nombre_nuevo */
  19.     strcpy(newn, PATH2);
  20.     strcat(newn, newname[i]);
  21.     rename(oldn, newn);
  22.   }
  23.   return 0;
  24. }

Saludos.
  #4 (permalink)  
Antiguo 25/10/2012, 21:05
 
Fecha de Ingreso: agosto-2012
Mensajes: 17
Antigüedad: 11 años, 8 meses
Puntos: 0
Respuesta: funcion rename

gracias vosk y ecfisa por responder ya entiendo un poco mas esta cuestion, averiguando un poco mas encontre que esto int main(int long, char *arg[]) me permite que la aplicacion trabaje independientemente de donde se instale pero aun no comprendo muy bien como usarlo, y me gustaria poder agregarles IF al programa de ecfisa ya que no siempre se llaman igual los archivos a renombrar
  #5 (permalink)  
Antiguo 26/10/2012, 02:01
 
Fecha de Ingreso: junio-2010
Ubicación: Madrid
Mensajes: 620
Antigüedad: 13 años, 10 meses
Puntos: 73
Respuesta: funcion rename

int main (int argc, char **argv)

Es el prototipo estandar de la función main. argc indica el número de argumentos que se han pasado al llamar al programa desde la línea de comando. argv es un arreglo de punteros a carácter, cada uno de estos punteros apunta a un argumento de los pasados en la línea de comando.

argv[0] siempre apunta a la cadena que contiene el nombre con el que se invocó el ejecutable, así, por ejemplo, si tenemos un ejecutable llamado renombra.exe, y desde la línea de comando escribimos

renombra

argc=1, y argv[0] = "renombra" (entiéndase el signo = como "apunta a"). argc siempre valdrá, como mínimo, 1.

renombra Nombre_archivo_1 Nombre_archivo_2

argc=3, argv[0] = "renombra", argv[1] = "Nombre_archivo_1", argv[2] = "Nombre_archivo_2"

Aquí ya tendrías el nombre del archivo a renombrar y el nombre del nuevo archivo. Ojo: Estos datos son solamente para lectura, si necesitas modificarlos (por ejemplo, añadirles un path a los nombres de archivo) no trabajes directamente sobre ellos, haz una copia en un arreglo de caracteres y trabaja sobre la copia.

Saludos,
  #6 (permalink)  
Antiguo 26/10/2012, 04:42
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: funcion rename

"...no siempre se llaman igual los archivos a renombrar..."

ecfisa te ha puesto un ejemplo de como trabajar los nombres y las rutas para ejecutar correctamente el rename, y Fw190 te ha dejado la forma de entrar nombres y rutas a traves de la linea de comandos; tienes que combinarlo un poco: en vez de tener la lista hardcoded de rutas la obtienes de los argumentos de la aplicacion, trabajas los valores para tener las rutas absolutas (la actual y la deseada) y aplicas rename.

El resto depende de como quieras diseñar la entrada de datos pq no hay un estandar (solo sabes que necesitas la ruta original y la ruta deseada, o algo que te permita deducirlo): puedes entrar los datos por pares (origen1 destino1 origen2 destino2...), por tipos (origen1 origen2 destino1 destino2), con modificadores (-p directorio -o nombre_origen -d nombre_destino...), o incluso puedes tirar la casa por la ventana y aceptar un archivo de datos formateado en xml descargado de la red con las rutas de trabajo y los nombres de archivo de origen y destino.

Personalmente usaría el modo grafico (todos los s.o. tienen la api para explorar archivos), pero si no puedes o no quieres usarlo, te propongo que uses modificadores que serían como definiciones previas al dato entrado, de forma que -p implicaría un cambio de directorio, -o sería un nombre de archivo de origen y -d un nombre archivo de destino ademas de punto de ejecucion de rename (son nombres arbitrarios, me los acabo de inventar y no forman parte de ningun estandar ni de nada documentado, en cualquier caso tendrías que documentarlos para distribuir tu propia aplicacion). Supongamos que tu programa se llama 'renombra.exe', está instalado en 'C:/renombra/' y lo ejecutas segun la siguiente cmdl:

renombra.exe -p C:/prueba -o a1.txt -d uno.txt -o a2.txt -d dos.txt

La aplicacion leerá la lista argv encontrando cada elemento (si un mismo elemento contiene espacios necesitará comillas ok? Si estas en C:/mis documentos tendras que indicarlo como "C:/mis documentos" porque el parser de argumentos corta por espacios)

La entrada a la aplicacion es la que te comenta Fw190, ahora tienes que recorrer los elementos comenzando por el 1 (ojo, el indice 1 es el segundo elemento; el primer elemento es el indice 0 y contiene el nombre del ejecutable), ademas tendras que trabajar con pares de datos (el primer será el atributo o llamalo como quieras, y el segundo el dato de trabajo):

Código:
int q;//incremental para el bucle
char *opr, *dat;//operacion y dato
//char cwd[512] = {'\0'};//directorio de trabajo
char org[512] = {'\0'};//ruta origen
char des[512] = {'\0'};//ruta destino

for(q = 1; q < argc; q++) {
    opr = argv[q];
    dat = argv[++q];
}
Ojo, no hay comprovacion de errores (si acaso dejalo para el final) y vamos a suponer que la la cmdl está bien construida. En cada ciclo obtienes una operacion y un dato; sabiendo que las operaciones validas son -p, -o y -d (me las he inventado, son arbitrarias), lo siguiente es diferenciar cada caso; para ello construyes una funcion que te retornará una descripcion inteligible de la accion a ejecutar con los datos disponibles:

Código:
enum modificadores {NADA, PATH, ORIGEN, DESTINO};
int quehago(char *bff) {
    int operacion = NADA;
    
    if(!strcmp("-p", bff)) operacion = PATH;
    else if(!strcmp("-o", bff)) operacion = ORIGEN;
    else if(!strcmp("-d", bff)) operacion = DESTINO;
    
    return operacion;
}
Ok? Ahora en cada bucle llamas a la funcion 'quehago' para saber como manipular el dato segun la operacion asignada:

Código:
switch(quehago(opr)) {
    ....
}
Tienes 4 opciones, en PATH tendras que aplicar un cambio de directorio de trabajo o copiar el dato a la cadena 'cwd' (o una cosa u otra, despues te lo comento con mas detalle), en ORIGEN tendras que copiar el dato a la cadena 'org', en DESTINO tendras que copiar el dato a la cadena 'des' y ejecutar la funcion rename con 'org' y 'des', y por ultimo con NADA no tienes que hacer nada o como mucho mostrar un error de modificador no aceptado o algo por el estilo (si llegas a este NADA sería bueno salir de la aplicacion antes que decrementar el contador 'q' para que no trate esa entrada como par de valores e intentar seguir como si nada).

Ya tienes las acciones, solo has de implementarlas para cada caso:

Código:
case PATH: {
    ...
}
break;
etc...
Para cambiar el directorio de trabajo (cada s.o. tiene su api con las funciones adaptadas) puedes llamar a 'chdir(char *wd)' con la nueva ruta, en el caso PATH tendras algo así:

Código:
chdir(dat);
//getcwd(cwd, sizeof(cwd));
Primero intentas cambiar de directorio (chdir retorna 0 si todo está correcto), o asignas el nuevo directorio a la variable de directorio de trabajo. Observa que en todo el ejemplo te estoy comentando las lineas de la variable del directorio de trabajo 'char cwd[]' porque hay dos formas de hacerlo; si cambias de directorio con 'chdir' no necesitas 'cwd' porque las rutas relativas de los nombres de archivo se aplicaran sobre el directorio de trabajo; si no cambias con chdir tendras que crear las rutas absolutas con la cadena 'cwd' mas la cadena de nombre archivo (origen y destino)

Para el caso ORIGEN, igual de facil, guardas el nombre de origen (o si trabajas sin modificar el directorio tendras que concatenar el nombre de archivo origen a cwd):

Código:
//sprintf(org, "%s\\%s", cwd, dat);//sin chdir
sprintf(org, dat);
Y finalmente DESTINO, parecido a ORIGEN pero haciendo la llamada al rename:

Código:
//sprintf(des, "%s\\%s", cwd, dat);//sin chdir
sprintf(des, dat);
rename(org, des);
Creo que la mejor forma es usando el chdir, te olvidas de la cadena 'cwd' y lo demas está mas claro. Ten en cuenta que el directorio de trabajo es el directorio de trabajo de esa aplicacion y no va a afectar a los demas procesos.

Otra cosa, no he puesto ninguna comprovacion de error, ni para el formato de la cmdl (se espera un modificar valido como segundo elemento, en caso contrario mostrar error y salir) ni para las funciones estandar. Tendrías que implementar esas comprovaciones.

Por cierto, los separadores de directorio \\ son para windows aunque creo que tambien soporta / igual que para los demas s.o.

Saludos
vosk

Última edición por vosk; 26/10/2012 a las 05:05

Etiquetas: funcion, int, programa, rename
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 14:50.