我需要帮助在 C 中获取文件信息
I need help getting file info in C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
// This program is pretty much a simulation of the ls command. Find out how to scan all of the files
// in the directory it's being run in and print out all the file names. Has to be in order.
int main(int argc, char* argv[])
{
// Don't worry about the else if, this is just a second part of my code that does not work entirely.
else if (strstr(argv[1], "-i")) // Long output
{
char **words = calloc(1000, sizeof(*words));
DIR *d;
struct dirent *dir; // Pointer for directory entry
d = opendir(".");
char* a = ".";
char* b = "..";
char* c = "ls";
int ret1, ret2, ret3, count = 0;
if (d) // opendir returns NULL if couldn't open directory
{
while ((dir = readdir(d)) != NULL)
{
ret1 = strcmp(dir->d_name, a); // Compare with the parent directory.
ret2 = strcmp(dir->d_name, b); // Compare with the parent directory.
ret3 = strcmp(dir->d_name, c); // Compare with the ls
if (ret1 == 0 || ret2 == 0 || ret3 == 0)
{
// Skip the ., .., and ls
}
else
{
words[count] = strdup(dir->d_name); // Put the file name in the array.
count++;
}
}
for (int i = 0; i < count; ++i) // Start readjusting the array in alphabetical order.
{
int imin = i;
for (int j = i + 1; j < count; ++j)
{
char word1[1000], word2[1000];
strcpy(word1, words[j]);
strcpy(word2, words[imin]);
for(int p = 0; word1[p]; p++)
{
word1[p] = tolower(word1[p]);
}
for(int p = 0; word2[p]; p++)
{
word2[p] = tolower(word2[p]);
}
if (strcmp(word1, word2) < 0)
{
imin = j;
}
}
char *tmp = words[i];
words[i] = words[imin];
words[imin] = tmp;
}
// Print every word in the array, but this time with metadata!
struct stat meta;
for (int i = 0; i < count; ++i)
{
stat(words[i], &meta);
int size = meta.st_size;
// How am I supposed to get read, write, execute info???
struct passwd *p;
struct group *grp;
uid_t uid = 0;
gid_t gid = 0;
if ((p = getpwuid(uid)) == NULL) // If username doesn't exist
{
printf("%d ", meta.st_uid); // User id
}
else
{
printf("%s ", p->pw_name); // User Name
}
if ((grp = getgrgid(gid)) == NULL) // If group name doesn't exist
{
printf("%d ", meta.st_gid); // Group id
}
else
{
printf("%s ", grp->gr_name); // Group Name
}
printf("%d ", size); // File Size
printf("%s ", ctime(&meta.st_mtime)); // bad date format
// I don't want the file name moving down.
printf("%s \n", words[i]); // File name
}
}
// Closing and freeing
closedir(d);
for (int a = 0; a < 1000; ++a)
{
free(words[a]);
}
free(words);
return 0;
}
}
目前我的代码给出了这个输出。
root root 435 Tue Oct 5 23:52:59 2021
find.c
root root 4562 Fri Oct 8 15:31:23 2021
ls.c
root root 58 Wed Oct 6 00:14:25 2021
Makefile
root root 296 Wed Oct 6 00:04:37 2021
tree.c
我的问题是它应该采用这种格式。
-rwxrw-r-- tim 用户 1252 9 月 28 日 14:00 find.c
第一个“-”应该是文件(-)或目录(d)的指示符,然后是用户、组等的检查、读、写、执行权限,然后是用户名(或用户id),组名(或组id),然后是文件大小,然后是修改时间,然后是文件名。
- 我不知道如何检查某物是文件还是目录。
- 我已经尝试查找读取权限的方法并且none有效。
- 我输出的日期格式与我尝试获取的输出不匹配,我不知道如何修复它。
- 使用我目前使用的日期格式,文件名会被排成一行,我不希望这样。
谁能帮我解决这个问题?
文件名前的换行符是因为ctime()
returns一个以换行符结尾的字符串。所以你应该删除它。
char *time = ctime(&meta.st_mtime);
time[strlen(time)-1] = '[=10=]'; // remove newline
printf("%s ", time);
要确定文件类型,请参见Checking if a file is a directory or just a file
要将权限转换为符号形式,请参阅Printing file permissions like 'ls -l' using stat(2) in C
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
// This program is pretty much a simulation of the ls command. Find out how to scan all of the files
// in the directory it's being run in and print out all the file names. Has to be in order.
int main(int argc, char* argv[])
{
// Don't worry about the else if, this is just a second part of my code that does not work entirely.
else if (strstr(argv[1], "-i")) // Long output
{
char **words = calloc(1000, sizeof(*words));
DIR *d;
struct dirent *dir; // Pointer for directory entry
d = opendir(".");
char* a = ".";
char* b = "..";
char* c = "ls";
int ret1, ret2, ret3, count = 0;
if (d) // opendir returns NULL if couldn't open directory
{
while ((dir = readdir(d)) != NULL)
{
ret1 = strcmp(dir->d_name, a); // Compare with the parent directory.
ret2 = strcmp(dir->d_name, b); // Compare with the parent directory.
ret3 = strcmp(dir->d_name, c); // Compare with the ls
if (ret1 == 0 || ret2 == 0 || ret3 == 0)
{
// Skip the ., .., and ls
}
else
{
words[count] = strdup(dir->d_name); // Put the file name in the array.
count++;
}
}
for (int i = 0; i < count; ++i) // Start readjusting the array in alphabetical order.
{
int imin = i;
for (int j = i + 1; j < count; ++j)
{
char word1[1000], word2[1000];
strcpy(word1, words[j]);
strcpy(word2, words[imin]);
for(int p = 0; word1[p]; p++)
{
word1[p] = tolower(word1[p]);
}
for(int p = 0; word2[p]; p++)
{
word2[p] = tolower(word2[p]);
}
if (strcmp(word1, word2) < 0)
{
imin = j;
}
}
char *tmp = words[i];
words[i] = words[imin];
words[imin] = tmp;
}
// Print every word in the array, but this time with metadata!
struct stat meta;
for (int i = 0; i < count; ++i)
{
stat(words[i], &meta);
int size = meta.st_size;
// How am I supposed to get read, write, execute info???
struct passwd *p;
struct group *grp;
uid_t uid = 0;
gid_t gid = 0;
if ((p = getpwuid(uid)) == NULL) // If username doesn't exist
{
printf("%d ", meta.st_uid); // User id
}
else
{
printf("%s ", p->pw_name); // User Name
}
if ((grp = getgrgid(gid)) == NULL) // If group name doesn't exist
{
printf("%d ", meta.st_gid); // Group id
}
else
{
printf("%s ", grp->gr_name); // Group Name
}
printf("%d ", size); // File Size
printf("%s ", ctime(&meta.st_mtime)); // bad date format
// I don't want the file name moving down.
printf("%s \n", words[i]); // File name
}
}
// Closing and freeing
closedir(d);
for (int a = 0; a < 1000; ++a)
{
free(words[a]);
}
free(words);
return 0;
}
}
目前我的代码给出了这个输出。
root root 435 Tue Oct 5 23:52:59 2021
find.c
root root 4562 Fri Oct 8 15:31:23 2021
ls.c
root root 58 Wed Oct 6 00:14:25 2021
Makefile
root root 296 Wed Oct 6 00:04:37 2021
tree.c
我的问题是它应该采用这种格式。 -rwxrw-r-- tim 用户 1252 9 月 28 日 14:00 find.c
第一个“-”应该是文件(-)或目录(d)的指示符,然后是用户、组等的检查、读、写、执行权限,然后是用户名(或用户id),组名(或组id),然后是文件大小,然后是修改时间,然后是文件名。
- 我不知道如何检查某物是文件还是目录。
- 我已经尝试查找读取权限的方法并且none有效。
- 我输出的日期格式与我尝试获取的输出不匹配,我不知道如何修复它。
- 使用我目前使用的日期格式,文件名会被排成一行,我不希望这样。
谁能帮我解决这个问题?
文件名前的换行符是因为ctime()
returns一个以换行符结尾的字符串。所以你应该删除它。
char *time = ctime(&meta.st_mtime);
time[strlen(time)-1] = '[=10=]'; // remove newline
printf("%s ", time);
要确定文件类型,请参见Checking if a file is a directory or just a file
要将权限转换为符号形式,请参阅Printing file permissions like 'ls -l' using stat(2) in C