0 / 0 / 0
Регистрация: 05.02.2020
Сообщений: 8
1

Переименовываем файлы\папки

05.02.2020, 20:07. Показов 3145. Ответов 9

Author24 — интернет-сервис помощи студентам
Hello world!
Появилось желание переименовать папки в каталоге.
По средствам не хитрых манипуляций с интернетом накидал следующий код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
using namespace std;
 
//strcpy, strcat
//_tcscpy,_tcscat
bool logick(vector<wchar_t> forSearch,wstring::const_iterator iTer)
{
    bool logicka = false;
    for (auto temp : forSearch) {
        if (*iTer == temp)
        {
            logicka = true;
            break;
        }
    }
    return logicka;
}
void reName(wstring &element,wstring::const_iterator iTer)
{
    int symbol;
    symbol = *iTer; element.erase(iTer);
    iTer = element.cbegin();
    element.insert(iTer, symbol);
}
int main()
{
    vector<wstring>fN; vector<wstring>newFolName;
    DWORD dwError = 0;
    setlocale(LC_ALL, "rus");
    WIN32_FIND_DATA find;
    wstring pytb = _T("e:\\Новая папка\\*");
    HANDLE hFind = FindFirstFile(_T("e:\\Новая папка\\*"), &find);
    {
        if (INVALID_HANDLE_VALUE == hFind)
        {
            cout << "Каталог не найден!" << endl;
      
            return dwError;
        }
        wstring name = { '.' };
        do {
            if (find.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY && find.dwFileAttributes != FILE_ATTRIBUTE_DEVICE)
            {
                _tprintf(_T("%s\n"), find.cFileName);
                if(name!=find.cFileName)
                fN.emplace_back(find.cFileName);// auto chekName = fN.cbegin();
                if(fN.size()==0)
                name = name + L'.';
               
            }
        } while (FindNextFile(hFind, &find) != NULL); FindClose(hFind);
 
        vector<wchar_t>forSearch{ '1', '2', '3', '4', '5', '6', '7', '8', '9', '0' };
        
       
        for_each(cbegin(fN), cend(fN), [forSearch,pytb,&newFolName](wstring element)
            {
                auto iTer = cend(element); advance(iTer,-5); 
                
                //true == logick(forSearch, iTer)
                while(logick(forSearch,iTer))
                {
                    reName(element, iTer);
                    logick(forSearch, iTer);
                }
                newFolName.emplace_back(pytb + element);
 
                });
     
 
    }
    if (size(newFolName) == 0)
    {
        printf_s("Нет файлов для изменения");
        return 0;
    }
    for(auto &addpytbFirst:fN)
    {
        addpytbFirst = pytb + addpytbFirst;
    }
 
    auto it2 = newFolName.cbegin();
    auto itfirstName = fN.cbegin(); 
    for (size_t i = fN.size(); i >0 ; i--,it2++,itfirstName++)
    {
   
        LPCTSTR newName = it2->c_str();
        LPCTSTR firstName = itfirstName->c_str();
        
       
        string sfsf =(char*)itfirstName->c_str();
        bool res = MoveFileW(firstName, newName); 
        if (rename((char*)it2->c_str(), (char*)itfirstName->c_str()) == 0) {
            cout << "true" << endl;
        }
      
    }
  
    dwError = GetLastError();
    if (dwError == ERROR_NO_MORE_FILES)
       {
               
                cout << "В каталоге нет файлов!" << endl;
               
                return dwError;
        }
     
        if (dwError)
            cout << "Файлы выведены на экран" << endl;
   
        return 0;
 }
Данный кот отработал в тестовом каталоге корректно. На "боевом" каталоге не сработало, ~150 объектов, перестав вносить изменения при любых обстоятельствах. MoweFileW возвращает всегда фолс(кроме первого айтима тру204), ренейм также не функцианирует. Есть мысли что поймал зловреда.
Это мой первый"проект" всё на костылях, не обращайте внимания.

Добавлено через 1 час 0 минут
Основной вопрос: есть ли возможные причины в данной реализации, или же искать причину в другом месте?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.02.2020, 20:07
Ответы с готовыми решениями:

Txt файлы из заданой папки
Пользователь задает путь к папке после чего программа считывает все txt файлы и отображает их...

как переместить файлы из папки?
Работаю в MFC. Требуется перемести все файлы (и папки) из каталога &quot;C:\ico\~&quot; в каталог &quot;C:\ico&quot;....

Выбирать файлы из папки и заносить их имена в массив
Всем привет. Возникла необходимость считывать все имена файлы из указанной директории в массив....

Как открыть все файлы из одной папки?
Напишите, пожалуйста, код, который выведет все данные из каждого файла в данной папке. Желательно,...

9
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
05.02.2020, 22:00 2
Цитата Сообщение от xZ83 Посмотреть сообщение
Основной вопрос: есть ли возможные причины в данной реализации, или же искать причину в другом месте?
Цитата Сообщение от xZ83 Посмотреть сообщение
if (rename((char*)it2->c_str(), (char*)itfirstName->c_str()) == 0) {
Для начала - убери здесь (char*), так делать нельзя
Цитата Сообщение от xZ83 Посмотреть сообщение
MoweFileW возвращает всегда фолс(кроме первого айтима тру204)
Проверь в этом случае,когда фолс, что возвращает ::GetLastError()
0
0 / 0 / 0
Регистрация: 05.02.2020
Сообщений: 8
06.02.2020, 09:01  [ТС] 3
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Для начала - убери здесь (char*), так делать нельзя

Проверь в этом случае,когда фолс, что возвращает ::GetLastError()
Кликните здесь для просмотра всего текста
C++
1
2
3
4
if (!MoveFileW(firstName, newName))
        {
            auto chekError = ::GetLastError();
        }

Для первой итеррации результат работы ::GetLastError(),unsigned long "3435973836",последующие "123" того же типа.
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
06.02.2020, 09:32 4
Цитата Сообщение от xZ83 Посмотреть сообщение
Для первой итеррации результат работы ::GetLastError(),unsigned long "3435973836",последующие "123" того же типа.
123 означает The filename, directory name, or volume label syntax is incorrect.
Посмотри, какие имена ты передаёшь в MoveFileW
0
0 / 0 / 0
Регистрация: 05.02.2020
Сообщений: 8
06.02.2020, 10:07  [ТС] 5
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
Посмотри, какие имена ты передаёшь в MoveFileW
Немного не понял вопрос, передаю имена подходящего типа(LPCTSTR).



Кликните здесь для просмотра всего текста

Переименовываем файлы\папки

0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
06.02.2020, 10:09 6
Лучший ответ Сообщение было отмечено xZ83 как решение

Решение

Цитата Сообщение от xZ83 Посмотреть сообщение
Немного не понял вопрос, передаю имена подходящего типа(LPCTSTR).
А что там за звёздочки? В имени файла их не должно быть.
1
0 / 0 / 0
Регистрация: 05.02.2020
Сообщений: 8
06.02.2020, 10:34  [ТС] 7
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
А что там за звёздочки? В имени файла их не должно быть.
В какой-то момент поставил звёздочку, и забыл. Спасибо вам, помогли разобраться! Логика сейчас работает, как для папок, так и для файлов.
0
0 / 0 / 0
Регистрация: 05.02.2020
Сообщений: 8
07.02.2020, 08:41  [ТС] 8
Немного оптимизировал код.
Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include <Windows.h>
#include <iostream>
#include <tchar.h>
#include <string>
#include <vector>
#include <algorithm>
typedef std::_String_const_iterator<std::_String_val<std::_Simple_types<wchar_t>>> iterWstr;
#define Folder
using namespace std;
 
//strcpy, strcat
//_tcscpy,_tcscat
 
 
iterWstr chekType(wstring element) {
 
    iterWstr sizeTypeIt = --cend(element);
#ifdef Folder
        return sizeTypeIt;
 #else
    do
    {
       --sizeTypeIt;
    } while (*sizeTypeIt != '.');
 
    return sizeTypeIt;
#endif // DEBUG
 
    //функция возвращает итератор указывающий на последний символ названия, пропуская формат.
}
//#define find.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY && find.dwFileAttributes != FILE_ATTRIBUTE_DEVICE
 
bool logick(const vector<wchar_t> forSearch, iterWstr iTer) {
    bool logicka = false;
    for (auto temp : forSearch) {
        if (*iTer == temp) {//ошибка че то с итерpатором, не тот?
            logicka = true;
            break;
        }
    }
    return logicka;
}
void reName(wstring& element) {
    int symbol = *chekType(element);
    element.erase(chekType(element));
    element.insert(cbegin(element), symbol);
    //Переносит символ в начало строки
}
int main() {
    vector<wstring>fN; vector<wstring>newFolName;
    DWORD dwError = 0;
    setlocale(LC_ALL, "rus");
    WIN32_FIND_DATA find;
    wstring pytb = _T("e:\\source\\Новая папка\\");
    HANDLE hFind = FindFirstFile(_T("e:\\source\\Новая папка\\*"), &find);
 
    if (INVALID_HANDLE_VALUE == hFind) {
        cout << "Каталог не найден!" << endl;
        //system("pause");
        return dwError;
    }
    wstring name = { '.' };
    do {
#ifdef  Folder
        if (find.dwFileAttributes == FILE_ATTRIBUTE_DIRECTORY && find.dwFileAttributes != FILE_ATTRIBUTE_DEVICE){
#else
        if (find.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY && find.dwFileAttributes != FILE_ATTRIBUTE_DEVICE){ 
#endif //  Folder
            _tprintf(_T("%s\n"), find.cFileName);//вывод имён элементов на экран
            if (name != find.cFileName)
                fN.emplace_back(find.cFileName);//копируем имена 
            if (fN.size() == 0)//фильтруем точки
                name = name + L'.';// Обходим все имена состоящие из точек.
        }
    } while (FindNextFile(hFind, &find) != NULL); FindClose(hFind);
 
    vector<wchar_t>forSearch{ '1','2','3','4','5','6','7','8','9','0','-' };
    // симболы подлежащие переносу в левую сторону
 
    for_each(cbegin(fN), cend(fN), [forSearch, pytb, &newFolName](wstring element){
 
        for (size_t i = 0; logick(forSearch, chekType(element)); i++) {
            if (i == 0)
                element.insert(cbegin(element), ' ');//add space if change this name
            reName(element);//edit this name
        }
        newFolName.emplace_back(pytb + element);
            });
 
   // FindClose(&hFind);
    if (size(newFolName) == 0) {//ловим пустой список
        printf_s("Нет файлов для изменения");
        return 0;
    }
    for(auto &addpytbFirst:fN){
        addpytbFirst = pytb + addpytbFirst;//сращиваем путь с названием
    }
    auto it2 = newFolName.cbegin(); //++it2; ++it2;
    auto itfirstName = fN.cbegin(); //++itfirstName; ++itfirstName;
    for (size_t i = fN.size(); i >0 ; i--,it2++,itfirstName++){
   
        LPCTSTR newName = it2->c_str();
        LPCTSTR firstName = itfirstName->c_str();
        //auto feds = newFolName.cend();
 
        if (!MoveFileW(firstName, newName)){
           auto chekError = ::GetLastError();
        }
 
       /* if (rename((char*)it2->c_str(), (char*)itfirstName->c_str()) == 0) {
            cout << "true" << endl;
        }  */
 
    }
    dwError = GetLastError();
    if (dwError == ERROR_NO_MORE_FILES){
                cout << "В каталоге нет файлов!" << endl;
                return dwError;
        }
 
        if (dwError)
            cout << "Файлы выведены на экран" << endl;
     
        return 0;
 }

Теперь не могу понять, как устранить ошибку итератора. В отладчике видно, что функция возвращает квадратики..
0
6579 / 4564 / 1843
Регистрация: 07.05.2019
Сообщений: 13,726
07.02.2020, 09:32 9
Лучший ответ Сообщение было отмечено xZ83 как решение

Решение

Цитата Сообщение от xZ83 Посмотреть сообщение
Теперь не могу понять, как устранить ошибку итератора. В отладчике видно, что функция возвращает квадратики..
iterWstr chekType(const wstring &element) {
Иначе ты возвращаешь указатель на копию строки, которая тут же уничтожается. Работай с индексами, если ещё не разобрался, что такое итераторы.
1
0 / 0 / 0
Регистрация: 05.02.2020
Сообщений: 8
07.02.2020, 10:27  [ТС] 10
Цитата Сообщение от oleg-m1973 Посмотреть сообщение
iterWstr chekType(const wstring &element) {
Иначе ты возвращаешь указатель на копию строки, которая тут же уничтожается.
Принцип работы понял.
0
07.02.2020, 10:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
07.02.2020, 10:27
Помогаю со студенческими работами здесь

Нужно просматривать папки и искать в них определенные файлы
Подскажите, как решить задачку! Есть папочка, а в ней еще много папочек, так вот нужно открывать...

Временные файлы папки Temp - как избежать ее удаления
Подскажите пожалуйста! Есть программа, после ее обновления папка sql удаляется из временной папки...

Как получить все папки и файлы хранящиеся на диске?
Здравствуйте! Помогите пожалуйста в написании кода, с помошью которого можно получить все папки...

Как удалить каталог, который имеет вложеные папки и файлы?
С помощью каких средств это можно реализовать? Есть функция _rmdir(const char*) в direct.h, но она...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
10
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru