linux c查找同名音频后缀
时间: 2025-08-20 13:03:03 浏览: 2
<think>我们将在Linux环境下使用C语言编写程序,查找同一目录中具有相同名称但不同音频后缀的文件。
思路:
1. 遍历指定目录下的所有文件。
2. 提取文件名(不含后缀)和文件后缀。
3. 对于每个文件名,记录其出现的所有不同后缀。
4. 如果同一个文件名对应多个不同的音频后缀,则输出该文件名及对应的后缀列表。
步骤:
- 使用目录操作函数(opendir, readdir)遍历目录。
- 分离文件名和后缀:例如,文件名为"test.mp3",则文件名为"test",后缀为"mp3"。
- 使用一个数据结构(如哈希表或链表)来存储每个文件名对应的后缀集合。
- 只关注音频文件后缀(如mp3, wav, flac, ogg等),可以定义一个音频后缀列表。
- 遍历完成后,输出所有具有多个不同音频后缀的文件名。
注意:由于文件名可能包含多个点,我们通常将最后一个点之后的部分视为后缀。
以下是一个简单的实现:</think>### 在 Linux 环境下使用 C 语言查找同名不同音频格式的文件
#### 解决方案思路
1. **遍历目录**:使用 `opendir()` 和 `readdir()` 扫描目标目录
2. **提取文件名**:分离文件名和扩展名
3. **建立映射**:使用哈希表存储同名文件的不同扩展名
4. **筛选音频**:检查扩展名是否为常见音频格式
5. **输出结果**:打印具有多个音频格式的同名文件
#### 完整代码实现
```c
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <string.h>
#include <ctype.h>
#include <sys/stat.h>
// 常见音频扩展名列表
const char *audio_extensions[] = {
"mp3", "wav", "flac", "ogg", "aac", "m4a", "wma", NULL
};
// 检查是否为音频文件
int is_audio_file(const char *ext) {
if (!ext) return 0;
for (int i = 0; audio_extensions[i]; i++) {
if (strcasecmp(ext, audio_extensions[i]) == 0) {
return 1;
}
}
return 0;
}
// 文件名结构体
struct FileEntry {
char *name;
char **extensions;
int count;
struct FileEntry *next;
};
// 主函数
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "用法: %s <目录路径>\n", argv[0]);
exit(EXIT_FAILURE);
}
DIR *dir = opendir(argv[1]);
if (!dir) {
perror("无法打开目录");
exit(EXIT_FAILURE);
}
struct FileEntry *file_map = NULL;
struct dirent *entry;
// 遍历目录
while ((entry = readdir(dir)) != NULL) {
// 跳过目录和隐藏文件
if (entry->d_type != DT_REG) continue;
char *dot = strrchr(entry->d_name, '.');
if (!dot || dot == entry->d_name) continue; // 无扩展名
// 分离文件名和扩展名
char *ext = dot + 1;
char name[256];
strncpy(name, entry->d_name, dot - entry->d_name);
name[dot - entry->d_name] = '\0';
// 只处理音频文件
if (!is_audio_file(ext)) continue;
// 在哈希表中查找或创建条目
struct FileEntry *curr = file_map;
struct FileEntry *prev = NULL;
while (curr) {
if (strcmp(curr->name, name) == 0) break;
prev = curr;
curr = curr->next;
}
if (!curr) {
// 创建新条目
curr = malloc(sizeof(struct FileEntry));
curr->name = strdup(name);
curr->extensions = malloc(8 * sizeof(char*)); // 初始分配8个扩展名空间
curr->count = 0;
curr->next = NULL;
if (prev) prev->next = curr;
else file_map = curr;
}
// 检查扩展名是否已存在
int found = 0;
for (int i = 0; i < curr->count; i++) {
if (strcasecmp(curr->extensions[i], ext) == 0) {
found = 1;
break;
}
}
// 添加新扩展名
if (!found) {
curr->extensions[curr->count] = strdup(ext);
curr->count++;
}
}
closedir(dir);
// 输出结果
printf("找到的同名多格式音频文件:\n");
printf("========================================\n");
struct FileEntry *curr = file_map;
int found_count = 0;
while (curr) {
if (curr->count > 1) {
printf("文件名: %s\n", curr->name);
printf("格式: ");
for (int i = 0; i < curr->count; i++) {
printf("%s%s", curr->extensions[i],
(i < curr->count - 1) ? ", " : "\n");
}
printf("----------------------------------------\n");
found_count++;
}
curr = curr->next;
}
if (!found_count) {
printf("未找到同名多格式音频文件\n");
} else {
printf("总计: %d 个文件\n", found_count);
}
// 清理内存
curr = file_map;
while (curr) {
struct FileEntry *next = curr->next;
free(curr->name);
for (int i = 0; i < curr->count; i++) {
free(curr->extensions[i]);
}
free(curr->extensions);
free(curr);
curr = next;
}
return EXIT_SUCCESS;
}
```
#### 编译与使用方法
1. 保存为 `find_audio_dupes.c`
2. 编译命令:
```bash
gcc -o find_audio_dupes find_audio_dupes.c
```
3. 运行命令:
```bash
./find_audio_dupes /path/to/your/music/directory
```
#### 示例输出
```
找到的同名多格式音频文件:
========================================
文件名: Beethoven_Moonlight_Sonata
格式: mp3, flac, wav
----------------------------------------
文件名: Vivaldi_Spring
格式: ogg, mp3, m4a
----------------------------------------
总计: 2 个文件
```
#### 关键特性说明
1. **音频格式识别**:支持常见音频格式如 MP3、WAV、FLAC 等
2. **大小写不敏感**:正确处理 `MP3` 和 `mp3` 等变体
3. **内存管理**:动态分配内存并正确释放
4. **高效查找**:使用链表实现简单哈希表
5. **可扩展性**:轻松添加新的音频格式支持
#### 扩展建议
1. **递归搜索**:添加 `-r` 参数支持子目录递归搜索
2. **格式过滤**:添加 `-e` 参数指定特定格式
3. **结果导出**:支持将结果输出到 CSV 文件
4. **自动处理**:添加删除/转换重复文件的选项
阅读全文
相关推荐

















