Avatar billede unsigned Nybegynder
26. december 2002 - 16:26 Der er 9 kommentarer og
2 løsninger

Hvordan omdøber man en fil?

Jeg har en programstump, der skal omdøbe alle filer i en mappe. Hvilken kommando skal bruges til at omdøbe filerne?




// Programmet 'rename_files' går ned i den angivne mappe, og omdøber alle filer.
// Den angivne mappe er altid "c:\Work\Soft\C++\filer"
// Filerne får navnene asd003, asd006 asd009, asd012 osv.
// Det vides ikke hvor mange filer der er i mappen.
// Mapperne i mappen røres ikke.
void rename_files(char *dir)
{
    WIN32_FIND_DATA fd;
    HANDLE handle;
    char absPath[MAX_PATH];
    char tempPath[MAX_PATH];
    strcpy(tempPath, dir);
    strcat(tempPath, "\\*.*");

    handle = FindFirstFile(tempPath, &fd);

    if(handle != INVALID_HANDLE_VALUE)
    {
        do
        {
            strcpy(absPath, dir);
            strcat(absPath, "\\");
            strcat(absPath, fd.cFileName);

            if(0 == strcmp(fd.cFileName, ".") || 0 == strcmp(fd.cFileName, ".."))
            {
                NULL;
            }
            else
            {
                if(fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
                {
                    // printf("file is dir - recurse: %s\n", absPath);
                    // deleteDir(absPath);
                    // printf("\tdeleting dir %s\n", absPath);
                    // RemoveDirectory(absPath);
                }
                else
                {
                    printf("\tRenaming file %s\n", absPath);
                    RenameFile(absPath);// Her skal også stå det nye filnavn.
                }
            }
        }while(FindNextFile(handle, &fd));
    }
    FindClose(handle);
}


// Mainprogram

int main(int argc, char **argv)
{
    // Skal drevet c skrives med stort eller småt?
    rename_files("c:\\Work\\Soft\\C++\\filer");

    cout << "\n\n\tTryk RETUR for at afslutte programmet.." ;
    getch() ;
    return 0;
}
Avatar billede unsigned Nybegynder
26. december 2002 - 16:27 #1
Den overflødige kode er med af udvidelses grunde.
Avatar billede soreno Praktikant
26. december 2002 - 16:42 #2
En måde at gøre det på:
char buffer[MAX_PATH];
sprintf(buffer, "ren %s %s", in_file_name, out_file_name);
system(buffer);

Evt. skal der puttes "" omkring filnavnene - specielt hvis der er mellemrum i navnene.

sprintf(buffer, "ren \"%s\" \"%s\"", in_file_name, out_file_name);
Avatar billede unsigned Nybegynder
26. december 2002 - 16:55 #3
Hej soreno. Du er vist en C++ haj. Jeg går igang med at implementere dit svar.
Avatar billede arne_v Ekspert
26. december 2002 - 19:44 #4
Jeg vil anbefale:

rename(in_file_name, out_file_name);

fordi:

1)  rename er hurtigere end system

2)  rename virker på alle platforme da den er ANSI C

PS: Du skal inkludere stdio.h for at kunne bruge den.
Avatar billede kamikaze Nybegynder
27. december 2002 - 02:46 #5
arne_v >> enig!
Avatar billede unsigned Nybegynder
27. december 2002 - 02:57 #6
Jeg har valgt at bruge

char buffer[MAX_PATH];
sprintf(buffer, "ren %s %s", in_file_name, out_file_name);
system(buffer);

Det skyldes at rename ikke anbringer den nynavngivne fil i den mappe, filen lå i. Den anbringer den nynavngivne fil i samme mappe som C++ exe filen ligger i.

Men der er et andet problem. Når Jeg kører programmet med sprintf, så nøjes programmet ikke med at hente alle filerne og omdøde dem. Når programmet har været hele turen igennem, så starter det forfra og tager den første fil igen. Denne første fil omdøbes, og så stopper programmet. Dvs at en fil omdøbes to gange og alle andre filer omdøbes en gang. Jeg har kørt programmet med rename, og den gør det ikke. Den omdøber alle filer en gang. Men rename kan som sagt ikke bruges, fordi den flytter filerne hen i exe mappen.

Alle med ideer er velkomne til at svare.
Avatar billede unsigned Nybegynder
27. december 2002 - 02:59 #7
Jeg lægger lige koden ud

// Dette program hedder C:\Work\Soft\C++\kanst.mak
// Ekstension mak skyldes C++ Builder
//---------------------------------------------------------------------------
#include <vcl\condefs.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <Cstring.h>
#include <string.h>
#include <conio.h>
#include <fstream.h>
//#include <iostream.h> iostream.h er inkluderet i fstream
#include <ctype.h>
#include <math.h>
#include <time.h>
#include <windows.h>

#pragma hdrstop // Bruges af C++ Builder

//---------------------------------------------------------------------------

ofstream hjkl("laes_her.txt") ;

class omdoeb
{
    public:

    void rename_files(char *dir) ;

    private:
    void laeg_tre_til(char *) ;
    void stop_001(int) ;
    bool for_kontrol(char *) ;
} ;

// Definitionsfil

// Funktionen laeg_tre_til lægge tre til den eksisterende filnavn. Rækken af
// filnavne får udseendet:
// asd003, asd006 asd009, asd012 osv.
void omdoeb::laeg_tre_til(char * navn)
{
    // Vi ved at filnavn altid består af 10 karakterer
    // Vi anbringer nu de tre cifre i en int variabel
    char et = navn[3] ;
    char to = navn[4] ;
    char tre = navn[5] ;
    int gammel = 0 ;
    gammel = gammel + ( 100 * ( ( (int)  et ) - 48 ) ) ;
    gammel = gammel + (  10 * ( ( (int)  to ) - 48 ) ) ;
    gammel = gammel + (  1 * ( ( (int) tre ) - 48 ) ) ;
    // Så lægger vi tre til
    gammel = gammel + 3 ;
    // Så konverteres til char
    // itoa(gammel, ny, 10);
    char ny[4] ;
    // hjkl << "Fra laeg_tre_til. Navn ser ud som: " << navn << "\n" ;
    // hjkl << "Fra laeg_tre_til. Gammel ser ud som: " << gammel << "\n" ;
    itoa (gammel, ny, 10) ;
    // hjkl << "Fra laeg_tre_til. Efter itoa. Ny ser ud som: " << ny << "\n" ;
    // hjkl << "Fra laeg_tre_til. Efter itoa. Gammel ser ud som: " << gammel << "\n" ;
    bool flag = 0 ;
    if ( (gammel < 10 ) && ( flag == 0 ) )
    {
        ny[2] = ny[0] ;
        ny[1] = '0' ;
        ny[0] = '0' ;
        flag = 1 ;
    }
    if ( ( gammel < 100 ) && ( flag == 0 ) )
    {
        ny[2] = ny[1] ;
        ny[1] = ny[0] ;
        ny[0] = '0' ;
        // flag = 1 ;
    }
    // hjkl << "Fra laeg_tre_til. Efter nulbehandling. \n" ;
    // hjkl << "Fra laeg_tre_til. Ny ser ud som: " << ny << "\n" ;
    // hjkl << "Fra laeg_tre_til. Gammel ser ud som: " << gammel << "\n" ;

    // Så dannes det nye filnavn
    navn[3] = ny[0] ;
    navn[4] = ny[1] ;
    navn[5] = ny[2] ;
    // hjkl << "Fra laeg_tre_til. Nyt filnavn ser ud som: " << navn << "\n" ;
}

// Programmet 'rename_files' går ned i den angivne mappe, og omdøber alle filer.
// Den angivne mappe er altid "c:\Work\Soft\C++\filer"
// Filerne får navnene asd003, asd006 asd009, asd012 osv.
// Det vides ikke hvor mange filer der er i mappen.
// Der må ikke ligge mapper i mappen.
// Hvis der gør, så afbrydes programkørslen.
// Der ligger muligvis for-filer i mappen. Disse for filer skal ikke røres.
// Længden af filnavnet på for-filer kendes ikke.
void omdoeb::rename_files(char *dir)
{
    WIN32_FIND_DATA fd;
    HANDLE handle;
    char absPath[MAX_PATH];
    char tempPath[MAX_PATH];
    strcpy(tempPath, dir);
    strcat(tempPath, "\\*.*");

    char nyt_filnavn[] = "asd000.txt" ;

    handle = FindFirstFile(tempPath, &fd);

    if(handle != INVALID_HANDLE_VALUE)
    {
        do
        {
            strcpy(absPath, dir);
            strcat(absPath, "\\");
            strcat(absPath, fd.cFileName);

            if(0 == strcmp(fd.cFileName, ".") || 0 == strcmp(fd.cFileName, ".."))
            {
                NULL;
            }
            else
            {
                if(fd.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY)
                {
                    // Programkørslen stoppes, hvis der er en mappe i mappen.
                    stop_001(573) ;
                }
                else
                {
                    hjkl << "Filen " << absPath << " omdøbes nu.\n" ;
                    // Her kontrolleres at filen ikke begynder med for.
                    if (for_kontrol(absPath) == 0)
                    {
                        laeg_tre_til(nyt_filnavn) ;
                        hjkl << "Efter laeg_tre_til. Nyt filnavn ser ud som: " << nyt_filnavn << "\n" ;
                        hjkl << "Filen " << absPath << " får navnet " << nyt_filnavn << "\n\n" ;

                        // char buffer[MAX_PATH];
                        // sprintf(buffer, "ren %s %s", absPath, nyt_filnavn);
                        // system(buffer);
                        rename(absPath, nyt_filnavn);
                    }
                }
            }
        }
        while(FindNextFile(handle, &fd));
    }
    FindClose(handle);
}

void omdoeb::stop_001(int tal)
{
    cout << "\n\tDer er fundet en fejl. Stop nr " << tal << "." ;
    cout << "\n\tDer er en mappe i mappen." ;
    cout << "\n\n\tTryk RETUR for at afslutte programmet." ;
    getch() ;
    exit(1) ;
}

bool omdoeb::for_kontrol(char * navn) // Ikke færdig
{
    bool retur ;
    retur = 0 ;
    return 0 ;
}

//---------------------------------------------------------------------------

// Mainprogram

int main(int argc, char **argv)
{
    hjkl << "Udskrift fra fil omdøbning.\n\n" ;

    omdoeb T ;
    // Skal drevet c skrives med stort eller småt?
    T.rename_files("c:\\Work\\Soft\\C++\\filer");

    cout << "\n\n\tTryk RETUR for at afslutte programmet." ;
    getch() ;
    return 0;
}
//---------------------------------------------------------------------------
Avatar billede unsigned Nybegynder
27. december 2002 - 03:16 #8
Der er en fejl i koden. Rename er brugt og sprintf er remarket. Det er på grund af en test. I den kode jeg foretrækker at bruge, er sprintf brugt og rename er remarket
Avatar billede arne_v Ekspert
27. december 2002 - 10:05 #9
Hvis rename flytter filerne hen i current directory, så
kan du jo enten putte sti på til-filnavnet eller lave
en chdir til directoriet inden du bruger rename. Så skulle
de gerne ende det rigtige sted.
Avatar billede arne_v Ekspert
27. december 2002 - 10:07 #10
Det er generelt risikabelt at ændre i et directory mens man
læser filnavne fra det.

Hvis du har memory nok kunen du overveje at læse alle filnavne til
memory først og så rename bagefter.
Avatar billede unsigned Nybegynder
29. december 2002 - 02:35 #11
Tak for alle svar og kommentarer. Programmet er færdigt og virker. Jeg endte med at bruge rename og lægge de omdøbte filer ned i en ny mappe.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester