注册 登录
编程论坛 C语言论坛

求助,字符串编辑,修改文件名

追梦人zmrghy 发布于 2022-05-20 03:07, 1729 次点击
修改文件名,好麻烦呀。。。
网上下载的视频,第一次下载6集,文件名中‘:’冒号是全角,  '('括号是半角。
第二次下载8集,文件名中‘:’冒号是全角,  '('括号是全角。
全角和半角,在char[ ]数组中是不同的。
string.rfind(''); 可以查找半角标点符号的位置,如何查找全角标点符号的位置?

写程序,折腾了半天,功能实现了。。。
程序,改的面目全非,惨不忍睹,自己都不忍心看了。。。
求大神,帮我修改一下。。。
多使用,字符串库函数,简化一下代码。。。。
下载的原文件名如下

空中浩劫第一季(国语配音) - 1.空中浩劫S01E01:联合航空811号班机(国语配音无字幕)(Av802929849,P1).mp4
空中浩劫第一季(国语配音) - 2.空中浩劫S01E02:美国航空1420号班机(国语配音无字幕)(Av802929849,P2).mp4
空中浩劫第一季(国语配音) - 3.空中浩劫S01E03:瑞士航空111号班机(国语配音无字幕)(Av802929849,P3).mp4
空中浩劫第一季(国语配音) - 4.空中浩劫S01E04:秘鲁航空603号班机(国语配音无字幕)(Av802929849,P4).mp4
空中浩劫第一季(国语配音) - 5.空中浩劫S01E05:阿拉斯加航空261号班机(国语配音无字幕)(Av802929849,P5).mp4
空中浩劫第一季(国语配音) - 6.空中浩劫S01E06:越洋航空236号班机(国语配音无字幕)(Av802929849,P6).mp4
空中浩劫系列(国语配音)2 - 2.空中浩劫S03E06:伊朗航空655号班机(国语配音)(Av467940195,P2).mp4
空中浩劫系列(国语配音)2 - 3.空中浩劫S03E08:埃及航空990号班机(国语配音)(Av467940195,P3).mp4
空中浩劫系列(国语配音)2 - 4.空中浩劫S04E07:墨西哥国际航空498号班机(国语配音)(Av467940195,P4).mp4
空中浩劫系列(国语配音)2 - 5.空中浩劫S11E01:巴西天马航空3054号班机(国语配音)(Av467940195,P5).mp4
空中浩劫系列(国语配音)2 - 6.空中浩劫S11E02:西加勒比海航空708号班机(国语配音)(Av467940195,P6).mp4
空中浩劫系列(国语配音)2 - 7.空中浩劫S11E09:尼日利亚航空2120号班机(国语配音)(Av467940195,P7).mp4
空中浩劫系列(国语配音)2 - 8.空中浩劫S11E10:太平洋西南航空1771号班机(国语配音)(Av467940195,P8).mp4
空中浩劫系列(国语配音)2 - 9.空中浩劫S11E13:美国联合航空232号班机(国语配音)(Av467940195,P9).mp4




修改后文件名如下

联合航空811号班机.mp4
美国航空1420号班机.mp4
瑞士航空111号班机.mp4
秘鲁航空603号班机.mp4
阿拉斯加航空261号班机.mp4
越洋航空236号班机.mp4
伊朗航空655号班机.mp4
埃及航空990号班机.mp4
墨西哥国际航空498号班机.mp4
巴西天马航空3054号班机.mp4
西加勒比海航空708号班机.mp4
尼日利亚航空2120号班机.mp4
太平洋西南航空1771号班机.mp4
美国联合航空232号班机.mp4
程序代码:

#include<iostream>
#include<io.h>
#include<string>
using namespace std;
void changeFileName(string path)
{
    char exte[5] = ".mp4";         //文件扩展名
    _finddata_t findData;
    intptr_t handle = _findfirst(path.c_str(), &findData);  //查找目录中的第一个文件
    if(handle == -1) throw exception("Error");
    do
    {
        char oldname[260] = {0};
        char newname[260] = {0};
            int j=0;
            strcpy(oldname, findData.name);
            for(j=0; j<128; j++)
            {
                if(oldname[j] == '-')  //原文件名中都有‘-’,防止文件改名后,再次被读入进行改名。。。
                    break;
            }
            if(j >= 128)
                continue;
            int i=0;
            while(!(oldname[i] == -93 && oldname[i+1] == -70))
                i++;
            i += 2;
            int start = i;
        for(; i<260; i++)
        {
            if(oldname[i] == 40||(oldname[i]== -93 && oldname[i+1] == -88))
                break;
            newname[i-start] = oldname[i];
        }
        strcat(newname,exte);        //添加文件扩展名 .mp4

        char old[512] = "C:\\Users\\Administrator\\Desktop\\[WPF]JJDown\\Download\\";
        char nwe[512] = "C:\\Users\\Administrator\\Desktop\\[WPF]JJDown\\Download\\";

        strcat(old, oldname);
        strcat(nwe, newname);
        rename(old, nwe);
    }while(_findnext(handle, &findData) == 0);      //找到目录中下一个文件
    _findclose(handle);
}

int main()
{
    string path = "C:\\Users\\Administrator\\Desktop\\[WPF]JJDown\\Download\\*.mp4";
    changeFileName(path);
    return 0;
}


源代码文件
只有本站会员才能查看附件,请 登录


完整项目
只有本站会员才能查看附件,请 登录
11 回复
#2
wp2319572022-05-20 07:00
回复 楼主 追梦人zmrghy
这个东西建议使用python   一条语句搞定
#3
rjsp2022-05-20 08:18
你这不是C,而是C++;并且,你用了 _findfirst 等C/C++标准库的东西。
既然用 C++ 了,为什么不用 std::filesystem::directory_entry 等C++标准的东西呢?

嗯……,我看了一下你的 rename.sln,你用的是 Visual Studio 2010,换个 Visual Studio 2012 吧,而且后者还是免费的
#4
追梦人zmrghy2022-05-20 10:22
回复 2楼 wp231957
C和C++还没学会,又要放弃吗?python果遇到困难,是不是又要换其它语言呀?


[此贴子已经被作者于2022-5-20 10:23编辑过]

#5
追梦人zmrghy2022-05-20 10:36
回复 3楼 rjsp
std::filesystem::directory_entry不是不用,是不会用。
VS2010也是免费的呀!!!
VS2010安装完成后,自动有授权了,不用再输入Key。
VS2010有帮助文档,不需要另外再下载。
VS2010自带中文发布打包程序,VS2012有没有我不清楚,VS2013和VS2015没有自带发布打包程序。
需要自己下载,还找不到中文的。只找到英又的发布打包程序。
#6
wp2319572022-05-20 12:42
回复 4楼 追梦人zmrghy
没关系,我只是告诉你 处理这种问题,10个c 也不是对手
程序代码:

handle=open(".//wp//mp4name.txt",encoding="utf-8")
import re
s=""
for x in handle:
    if ":" in x:
       s=x.split(":")[1][:-1]
    elif "" in x:
       s=x.split("")[1][:-1]
    s=re.sub("\(.+?\)|(.+?)","",s)      
    print(s)


'''
PS D:\wp> & C:/Programs/Python/python.exe d:/wp/wp/wp1.py
    联合航空811号班机.mp4
    美国航空1420号班机.mp4
    瑞士航空111号班机.mp4
    秘鲁航空603号班机.mp4
    阿拉斯加航空261号班机.mp4
    越洋航空236号班机.mp4
    伊朗航空655号班机.mp4
    埃及航空990号班机.mp4
    墨西哥国际航空498号班机.mp4
    巴西天马航空3054号班机.mp4
    西加勒比海航空708号班机.mp4
    尼日利亚航空2120号班机.mp4
    太平洋西南航空1771号班机.mp4
    美国联合航空232号班机.mp
PS D:\wp>
'''

#7
追梦人zmrghy2022-05-20 13:27
回复 6楼 wp231957
没看懂你写的什么意界,新文件名,是从原文件名中获取的一部分。而不是文件名.TXT文件。
#8
wp2319572022-05-20 13:29
回复 7楼 追梦人zmrghy
嗯哪,我有没有那些文件,所以我只是把你的复制过来,实际上操作目录也狠容易
#9
rjsp2022-05-20 13:39
回复 5楼 追梦人zmrghy
好吧,那我也不多说了。我给你一个标准C++写的代码,你使用任何符合标准的C++编译器都可以运行它

程序代码:
#include <iostream>
#include <filesystem>
#include <algorithm>
using namespace std;

bool ReduceFileName( const std::filesystem::path& path )
{
    auto make_name_name = []( const std::wstring& filename )
    {
        size_t a = filename.find( L'' );
        if( a != std::wstring::npos )
        {
            a = filename.find_first_not_of( L"\t\n\v\f\r ", a+1 );
            size_t b = filename.find_first_of( L"((", a );
            b = filename.find_last_not_of( L"\t\n\v\f\r ", b-1 );
            return filename.substr( a, b+1-a );
        }
        return filename;
    };

    using namespace std::filesystem;
    try
    {
        for( auto& entry : directory_iterator(path) )
        {
            if( entry.is_regular_file() ) // 只处理常规文件
            {
                auto ext = entry.path().extension().generic_wstring(); // 扩展名
                std::for_each( begin(ext), end(ext), [](auto& c){if(c>=L'A'&&c<=L'Z') c+=L'a'-L'A';} ); // 扩展名转化成小写
                if( ext == L".mp4" )
                {
                    const auto& old_name = entry.path().stem().generic_wstring();
                    const auto& new_name = make_name_name( old_name );
                    if( old_name != new_name )
                    {
                        wcout << old_name << L" -> " << new_name;

                        auto new_path = entry.path().parent_path()/(new_name+L".mp4");
                        if( exists(new_path) ) // 新文件名已经存在
                        {
                            wcout << L" --- [failed] 文件已存在";
                        }
                        else
                        {
                            std::error_code ec;
                            rename( entry, new_path, ec );
                            if( ec )
                                cout << " --- [failed] " << ec.message();
                        }

                        wcout << L'\n';
                    }
                }
            }
        }
    }
    catch( const std::exception& e )
    {
        cout << "[failed] " << e.what() << '\n';
        return false;
    }
    return true;
}

int main( void )
{
    wcout.imbue( std::locale(std::locale(),"",std::locale::ctype) );
    ReduceFileName( u8R"(C:\Users\Administrator\Desktop\[WPF]JJDown\Download\)" ); // 使用 Unicode 可避免GBK认字不全
}
#10
追梦人zmrghy2022-05-20 17:30
回复 9楼 rjsp
好的,虽然有些代码,看不懂,试验一下就知道它的作用了,谢谢!!!
#11
追梦人zmrghy2022-05-23 20:26
回复 9楼 rjsp
全部注释掉,只留个空函数,还是有错

程序代码:

#include <iostream>
#include <filesystem>
#include <algorithm>
using namespace std;

bool ReduceFileName(const std::filesystem::path& path)
{
    //auto make_name_name = [](const std::wstring& filename)
   
//{
   
//    size_t a = filename.find(L':');
   
//    if (a != std::wstring::npos)
   
//    {
   
//        a = filename.find_first_not_of(L"\t\n\v\f\r ", a + 1);
   
//        size_t b = filename.find_first_of(L"((", a);
   
//        b = filename.find_last_not_of(L"\t\n\v\f\r ", b - 1);
   
//        return filename.substr(a, b + 1 - a);
   
//    }
   
//    return filename;
   
//};

   
//using namespace std::filesystem;
   
//try
   
//{
   
//    for (auto& entry : directory_iterator(path))
   
//    {
   
//        if (entry.is_regular_file()) // 只处理常规文件
   
//        {
   
//            auto ext = entry.path().extension().generic_wstring(); // 扩展名
   
//            std::for_each(begin(ext), end(ext), [](auto& c) {if (c >= L'A'&&c <= L'Z') c += L'a' - L'A'; }); // 扩展名转化成小写
   
//            if (ext == L".mp4")
   
//            {
   
//                const auto& old_name = entry.path().stem().generic_wstring();
   
//                const auto& new_name = make_name_name(old_name);
   
//                if (old_name != new_name)
   
//                {
   
//                    wcout << old_name << L" -> " << new_name;

   
//                    auto new_path = entry.path().parent_path() / (new_name + L".mp4");
   
//                    if (exists(new_path)) // 新文件名已经存在
   
//                    {
   
//                        wcout << L" --- [failed] 文件已存在";
   
//                    }
   
//                    else
   
//                    {
   
//                        std::error_code ec;
   
//                        rename(entry, new_path, ec);
   
//                        if (ec)
   
//                            cout << " --- [failed] " << ec.message();
   
//                    }

   
//                    wcout << L'\n';
   
//                }
   
//            }
   
//        }
   
//    }
   
//}
   
//catch (const std::exception& e)
   
//{
   
//    cout << "[failed] " << e.what() << '\n';
   
//    return false;
   
//}
    return true;
}

int main(void)
{
    wcout.imbue(std::locale(std::locale(), "", std::locale::ctype));
    ReduceFileName(u8R"(C:\Users\Administrator\Desktop\[WPF]JJDown\Download\)"); // 使用 Unicode 可避免GBK认字不全
}


>------ 已启动生成: 项目: test3, 配置: Debug Win32 ------
1>  test3.cpp
1>test3.cpp(6): error C3083: “filesystem”:“::”左侧的符号必须是一种类型
1>test3.cpp(6): error C2039: “path”: 不是“std”的成员
1>  C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\filesystem(26): note: 参见“std”的声明
1>test3.cpp(6): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>test3.cpp(6): error C2143: 语法错误: 缺少“,”(在“&”的前面)
1>test3.cpp(68): error C2664: “bool ReduceFileName(const int)”: 无法将参数 1 从“const char [53]”转换为“const int”
1>  test3.cpp(68): note: 没有使该转换得以执行的上下文
========== 生成: 成功 0 个,失败 1 个,最新 0 个,跳过 0 个 ==========
#12
追梦人zmrghy2022-05-23 21:27
回复 9楼 rjsp
std::filesystem
C++17 VS2019才能使用对吗???
VS2015,无法使用对吗???
1