(使用 C):访问目录中的每个文件并逐个编辑其内容
(Using C): Accessing each file in a directory and editing its contents, one by one
我是一名初级程序员(目前正在学习如何使用哈希表和尝试之类的东西),因此信息不灵通,非常重视您的建议。
我想编写一个程序:
- 接收目录地址作为 argv。
- 逐一检查该目录中的每个文件(它们都是 BMP)并在读取到缓冲区后...
- 对该缓冲区中的 RGB 值执行一个函数,没有什么特别的 -- 想象一下类似框模糊或灰度函数的东西。
- 将缓冲区保存到新文件夹中的文件,关闭当前正在访问的原始目录中的文件,然后移动到下一个文件,直到到达最终文件。
我正在尽我所能试验 dirent,但无论我如何表述这个问题,我最终得到的结果告诉我如何读取文件名并列出它们,以及如何将它们读入 dirent 结构本身不保存文件数据;我对专门访问目录并在其中查找文件的明确目的一无所知 fopen()ing 他们。
我的代码摘录,给你一个我的(可能很糟糕的)逻辑的例子:
DIR *folder;
folder = opendir(argv[3]);
if (folder == NULL);
{
printf("Unable to read folder");
return 2;
}
struct dirent *input;
FILE *fileinput;
int files = 0;
// Use this file loop to go through each
while( (input = readdir(folder)) != NULL )
{
fileinput = fopen(input->d_name, "r");
if (filepointer != NULL)
{
// checks for file headers, open another FILE for writing, my actual function etc.
}
但是,似乎那里的 FOPEN 正在访问名称的副本,而不是文件本身如此指示。而且我根本没有词汇来找到类似的问题来回答这个问题,在 SO 或其他地方。
有人介意给我指明正确的方向吗?对于任何麻烦,我深表歉意,因为我确定这是一个非常基本的问题...
ーーーー编辑:请求 post 更新代码以供审查:
#include <dirent.h> //必要
#include <sys/types.h>
#include "helpers.h" //bmp.h declared within
#include <getopt.h> //parse argvs
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
const int PATH_MAX = 260;
int main(int argc, char *argv[])
{
char *filters = "rbg";
char filter = getopt(argc, argv, filters);
if (filter == '?') {
printf("Invalid filter.\nUsage: ./colourfilter [flag]\n r = red\t b = blue\t g = green\n");
return 2;
}
if (getopt(argc, argv, filters) != -1) {
printf("Only one filter may be used.\n");
return 3;
}
// OPEN INPUT FOLDER
const char *inputs = "inputs";
DIR *infolder = opendir(inputs);
if (infolder == NULL) {
//fprintf(stderr,"Unable to read folder %s\n", infolder);
printf("Unable to read folder.\n");
return 4;
}
// Declare variables
struct dirent *input;
int counter = 0;
char name[8];
FILE *imgout;
while((input = readdir(infolder)) != NULL)
{
char path[PATH_MAX];
if (!strcmp(input->d_name, ".") || !strcmp(input->d_name, "..")) {
continue;
}
if ((size_t)snprintf(path, sizeof(path), "%s/%s", infolder, input->d_name) >= sizeof(path)) {
printf("Filename too long: %s/%s\n", infolder, input->d_name);
continue;
}
// FOPEN THINGS
// "Also make sure you open the BMP files as binary with "rb" and "wb".:" (see:
sprintf(name, "%03i.bmp", counter);
FILE *imgin = fopen(path, "rb");
imgout = fopen(name, "wb");
if (imgin == NULL) {
printf("Could not open %s.\n", path);
return 7;
}
if (imgout == NULL) {
fclose(imgin);
printf("Could not create images.\n");
return 8;
}
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, imgin);
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, imgin);
// Ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
bi.biBitCount != 24 || bi.biCompression != 0)
{
fclose(imgout);
fclose(imgin);
printf("Unsupported file format.\n");
return 8;
} // ... other stuff after this for implementing functions etc.
问题是 fopen(input->d_name, "r");
尝试打开当前目录中的文件,而不是 argv[3]
中指定的文件。您必须在单独的字符串中构建文件路径。
还要确保使用 "rb"
和 "wb"
.
打开二进制 BMP 文件
char *foldername = argv[3];
DIR *folder = opendir(foldername);
if (folder == NULL) {
fprintf(stderr, "Unable to read folder %s\n", foldername);
return 2;
}
struct dirent *input;
FILE *fileinput;
int files = 0;
// Use this file loop to go through each
while ((input = readdir(folder)) != NULL) {
char path[PATH_MAX];
if (!strcmp(input->d_name, ".") || !strcmp(input->d_name, "..")) }
continue;
}
if ((size_t)snprintf(path, sizeof path, "%s/%s", foldername, input->d_name) >= sizeof path) {
fprintf(stderr, "filename too long: %s/%s\n", foldername, input->d_name);
continue;
}
fileinput = fopen(path, "rb");
...
我是一名初级程序员(目前正在学习如何使用哈希表和尝试之类的东西),因此信息不灵通,非常重视您的建议。
我想编写一个程序:
- 接收目录地址作为 argv。
- 逐一检查该目录中的每个文件(它们都是 BMP)并在读取到缓冲区后...
- 对该缓冲区中的 RGB 值执行一个函数,没有什么特别的 -- 想象一下类似框模糊或灰度函数的东西。
- 将缓冲区保存到新文件夹中的文件,关闭当前正在访问的原始目录中的文件,然后移动到下一个文件,直到到达最终文件。
我正在尽我所能试验 dirent,但无论我如何表述这个问题,我最终得到的结果告诉我如何读取文件名并列出它们,以及如何将它们读入 dirent 结构本身不保存文件数据;我对专门访问目录并在其中查找文件的明确目的一无所知 fopen()ing 他们。
我的代码摘录,给你一个我的(可能很糟糕的)逻辑的例子:
DIR *folder;
folder = opendir(argv[3]);
if (folder == NULL);
{
printf("Unable to read folder");
return 2;
}
struct dirent *input;
FILE *fileinput;
int files = 0;
// Use this file loop to go through each
while( (input = readdir(folder)) != NULL )
{
fileinput = fopen(input->d_name, "r");
if (filepointer != NULL)
{
// checks for file headers, open another FILE for writing, my actual function etc.
}
但是,似乎那里的 FOPEN 正在访问名称的副本,而不是文件本身如此指示。而且我根本没有词汇来找到类似的问题来回答这个问题,在 SO 或其他地方。
有人介意给我指明正确的方向吗?对于任何麻烦,我深表歉意,因为我确定这是一个非常基本的问题...
ーーーー编辑:请求 post 更新代码以供审查:
#include <dirent.h> //必要
#include <sys/types.h>
#include "helpers.h" //bmp.h declared within
#include <getopt.h> //parse argvs
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <math.h>
#include <string.h>
const int PATH_MAX = 260;
int main(int argc, char *argv[])
{
char *filters = "rbg";
char filter = getopt(argc, argv, filters);
if (filter == '?') {
printf("Invalid filter.\nUsage: ./colourfilter [flag]\n r = red\t b = blue\t g = green\n");
return 2;
}
if (getopt(argc, argv, filters) != -1) {
printf("Only one filter may be used.\n");
return 3;
}
// OPEN INPUT FOLDER
const char *inputs = "inputs";
DIR *infolder = opendir(inputs);
if (infolder == NULL) {
//fprintf(stderr,"Unable to read folder %s\n", infolder);
printf("Unable to read folder.\n");
return 4;
}
// Declare variables
struct dirent *input;
int counter = 0;
char name[8];
FILE *imgout;
while((input = readdir(infolder)) != NULL)
{
char path[PATH_MAX];
if (!strcmp(input->d_name, ".") || !strcmp(input->d_name, "..")) {
continue;
}
if ((size_t)snprintf(path, sizeof(path), "%s/%s", infolder, input->d_name) >= sizeof(path)) {
printf("Filename too long: %s/%s\n", infolder, input->d_name);
continue;
}
// FOPEN THINGS
// "Also make sure you open the BMP files as binary with "rb" and "wb".:" (see:
sprintf(name, "%03i.bmp", counter);
FILE *imgin = fopen(path, "rb");
imgout = fopen(name, "wb");
if (imgin == NULL) {
printf("Could not open %s.\n", path);
return 7;
}
if (imgout == NULL) {
fclose(imgin);
printf("Could not create images.\n");
return 8;
}
BITMAPFILEHEADER bf;
fread(&bf, sizeof(BITMAPFILEHEADER), 1, imgin);
BITMAPINFOHEADER bi;
fread(&bi, sizeof(BITMAPINFOHEADER), 1, imgin);
// Ensure infile is (likely) a 24-bit uncompressed BMP 4.0
if (bf.bfType != 0x4d42 || bf.bfOffBits != 54 || bi.biSize != 40 ||
bi.biBitCount != 24 || bi.biCompression != 0)
{
fclose(imgout);
fclose(imgin);
printf("Unsupported file format.\n");
return 8;
} // ... other stuff after this for implementing functions etc.
问题是 fopen(input->d_name, "r");
尝试打开当前目录中的文件,而不是 argv[3]
中指定的文件。您必须在单独的字符串中构建文件路径。
还要确保使用 "rb"
和 "wb"
.
char *foldername = argv[3];
DIR *folder = opendir(foldername);
if (folder == NULL) {
fprintf(stderr, "Unable to read folder %s\n", foldername);
return 2;
}
struct dirent *input;
FILE *fileinput;
int files = 0;
// Use this file loop to go through each
while ((input = readdir(folder)) != NULL) {
char path[PATH_MAX];
if (!strcmp(input->d_name, ".") || !strcmp(input->d_name, "..")) }
continue;
}
if ((size_t)snprintf(path, sizeof path, "%s/%s", foldername, input->d_name) >= sizeof path) {
fprintf(stderr, "filename too long: %s/%s\n", foldername, input->d_name);
continue;
}
fileinput = fopen(path, "rb");
...