/*
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)!專注于網(wǎng)頁設(shè)計、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序定制開發(fā)、集團企業(yè)網(wǎng)站建設(shè)等服務(wù)項目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了呼圖壁免費建站歡迎大家使用!
* 此程序可以ls 多個文件
* 范例: ./myls file1 file2 dt1 dt2 后面參數(shù)可以多個,
*
*/
#include pwd.h
#include grp.h
#include sys/types.h
#include sys/stat.h
#include fcntl.h
#include unistd.h
#include stdlib.h
#include string.h
#include dirent.h
#include limits.h
#include time.h
#include stdio.h
/*
* 讀取不是目錄的文件
* argv : 文件名
* 返回值: 出錯1, 正確0
*/
int lsregfile(char *argv) //讀取不是目錄的文件
{
struct stat buf;
if (lstat(argv, buf) 0) //讀取文件信息。
{
printf("%s:stat error\n",argv);
return 1;
}
char str[10] = "";
/******************判斷文件的類型***********************/
if (S_ISREG(buf.st_mode)) str[0] = '-';
else if (S_ISDIR(buf.st_mode)) str[0] = 'd';
else if (S_ISCHR(buf.st_mode)) str[0] = 'c';
else if (S_ISBLK(buf.st_mode)) str[0] = 'b';
else if (S_ISFIFO(buf.st_mode)) str[0] = 'p';
#ifdef S_ISLNK
else if (S_ISLNK(buf.st_mode)) str[0] = 'l';
#endif
#ifdef S_ISSOCK
else if (S_ISSOCK(buf.st_mode)) str[0] = 's';
#endif
else str[0] = 'U'; //表示未知文件類型
/************************* 輸出權(quán)限 ************************/
str[1] = ((buf.st_mode S_IRUSR) != 0) ? 'r' : '-';
str[2] = ((buf.st_mode S_IWUSR) != 0) ? 'w' : '-';
str[3] = ((buf.st_mode S_IXUSR) != 0) ? 'x' : '-';
//判斷設(shè)置-用戶-ID
str[3] = ((buf.st_mode S_ISUID) != 0) ? 's' : str[3];
str[4] = ((buf.st_mode S_IRGRP) != 0) ? 'r' : '-';
str[5] = ((buf.st_mode S_IWGRP) != 0) ? 'w' : '-';
str[6] = ((buf.st_mode S_IXGRP) != 0) ? 'x' : '-';
//判斷設(shè)置-用戶組-ID
str[6] = ((buf.st_mode S_ISGID) != 0) ? 'x' : str[6];
str[7] = ((buf.st_mode S_IROTH) != 0) ? 'r' : '-';
str[8] = ((buf.st_mode S_IWOTH) != 0) ? 'w' : '-';
str[9] = ((buf.st_mode S_IXOTH) != 0) ? 'x' : '-';
printf("%s ", str);
// 輸出硬鏈接數(shù)
printf("%3ld ", (long) buf.st_nlink);
// 輸出文件所有者。
struct passwd *ppd;
ppd = getpwuid(buf.st_uid);
printf("%-5s ", ppd-pw_name);
// 輸出文件所有者的組名
struct group *pgroup;
pgroup = getgrgid(buf.st_gid);
printf("%-5s ", pgroup-gr_name);
// 輸出文件大小
printf("%5lld ", (long long) buf.st_size);
// 輸出最近修改時間
struct tm *ptime = NULL;
ptime = gmtime(buf.st_mtime);
printf("%.4d-%.2d-%.2d %.2d:%.2d ",
(1900 + ptime-tm_year),
(1 + ptime-tm_mon),
ptime-tm_mday,
ptime-tm_hour,
ptime-tm_min);
// 輸出文件名
printf("%s", argv);
if (str[0] == 'l') //如果是鏈接文件,獲取鏈接對象名
{
printf(" - ");
char linkbuf[100] = "";
if (readlink(argv, linkbuf, sizeof(buf)) 0 )
{
printf("%s: readlink error\n",argv);
return 1;
}
printf("%s", linkbuf);
}
printf("\n");
return 0;
}
/*
* 讀取目錄里面不帶.和..的所有文件的信息.
* argv : 文件名
* 返回值: 出錯1, 正確0
*/
int lsdir(char *argv) //讀取目錄
{
printf("%s:\n", argv);
DIR *pread;
pread = opendir(argv);// 打開目錄
if (pread == NULL)
{
printf("%s: opendir error\n",argv);
return 1;
}
if (chdir(argv) 0) //修改工作目錄 使下面的stat能成功.
{
printf("%s chdir error\n", argv);
return 1;
}
struct dirent *pd = NULL;
long long ssize = 0;
while ((pd = readdir(pread)) != NULL)
{
if ((!strcmp(pd-d_name, ".")) || (!strcmp(pd-d_name, "..")))
continue; //當文件為.或..時跳過。
struct stat buf;
if (lstat(pd-d_name, buf) 0) //讀取文件信息。
{
printf("%s: stat error\n", argv);
return 1;
}
char str[10] = "";
/******************判斷文件的類型***********************/
if (S_ISREG(buf.st_mode)) str[0] = '-';
else if (S_ISDIR(buf.st_mode)) str[0] = 'd';
else if (S_ISCHR(buf.st_mode)) str[0] = 'c';
else if (S_ISBLK(buf.st_mode)) str[0] = 'b';
else if (S_ISFIFO(buf.st_mode)) str[0] = 'p';
#ifdef S_ISLNK
else if (S_ISLNK(buf.st_mode)) str[0] = 'l';
#endif
#ifdef S_ISSOCK
else if (S_ISSOCK(buf.st_mode)) str[0] = 's';
#endif
else str[0] = 'U'; //表示未知文件類型
/************************* 輸出權(quán)限 ************************/
str[1] = ((buf.st_mode S_IRUSR) != 0) ? 'r' : '-';
str[2] = ((buf.st_mode S_IWUSR) != 0) ? 'w' : '-';
str[3] = ((buf.st_mode S_IXUSR) != 0) ? 'x' : '-';
//判斷設(shè)置-用戶-ID
str[3] = ((buf.st_mode S_ISUID) != 0) ? 's' : str[3];
str[4] = ((buf.st_mode S_IRGRP) != 0) ? 'r' : '-';
str[5] = ((buf.st_mode S_IWGRP) != 0) ? 'w' : '-';
str[6] = ((buf.st_mode S_IXGRP) != 0) ? 'x' : '-';
//判斷設(shè)置-用戶組-ID
str[6] = ((buf.st_mode S_ISGID) != 0) ? 'x' : str[6];
str[7] = ((buf.st_mode S_IROTH) != 0) ? 'r' : '-';
str[8] = ((buf.st_mode S_IWOTH) != 0) ? 'w' : '-';
str[9] = ((buf.st_mode S_IXOTH) != 0) ? 'x' : '-';
printf("%s ", str);
// 輸出硬鏈接數(shù)
printf("%3ld ", (long) buf.st_nlink);
// 輸出文件所有者。
struct passwd *ppd;
ppd = getpwuid(buf.st_uid);
printf("%-5s ", ppd-pw_name);
// 輸出文件所有者的組名
struct group *pgroup;
pgroup = getgrgid(buf.st_gid);
printf("%-5s ", pgroup-gr_name);
// 輸出文件大小
printf("%5lld ", (long long) buf.st_size);
ssize += buf.st_size;
// 輸出最近修改時間
struct tm *ptime = NULL;
ptime = gmtime(buf.st_ctime);
printf("%.4d-%.2d-%.2d %.2d:%.2d ",
(1900 + ptime-tm_year),
(1 + ptime-tm_mon),
ptime-tm_mday,
ptime-tm_hour,
ptime-tm_min);
// 輸出文件名
printf("%s", pd-d_name);
if (str[0] == 'l') //如果是鏈接文件,獲取鏈接對象名
{
printf(" - ");
char linkbuf[100] = "";
if (readlink(pd-d_name, linkbuf, sizeof(buf)) 0 )
{
printf("%s: readlink error\n", argv);
return 1;
}
printf("%s", linkbuf);
}
printf("\n");
}
// 輸出總用量
printf("總用量 %lld\n", ssize/1024);
///////////////////////////////////////////////////////
if (closedir(pread) 0) //關(guān)閉目錄
{
printf("%s: closedir error\n", argv);
return 1;
}
}
/*
*
* 這個程序,把非目錄文件和目錄分開讀。
*
*/
int main(int argc, char *argv[])
{
if (argc == 1)
{
printf("the argument is wrong\n");
exit(1);
}
int i;
for (i = 1; i argc; ++i)
{
// 保存當前的工作目錄。以便返回當前工作目錄
char bufpwd[80];
char *getp =NULL;
getp = getcwd(bufpwd, sizeof(bufpwd));
if (getp == NULL)
{
printf("%s : getcwd error\n",argv[i]);
return 1;
}
struct stat buf0; //獲取文件信息
if (stat(argv[i], buf0) 0)
{
printf("%s: stat error\n", argv[i]);
continue; //出錯跳過
}
if (!S_ISDIR(buf0.st_mode)) //如果讀取的不是目錄。就直接去讀文件。
lsregfile(argv[i]); //讀文件
else
lsdir(argv[i]); //讀目錄
// 改變工作目錄回原來的工作目錄,以便讀取相對路徑的文件
if (chdir(bufpwd) 0)
{
printf("%s : chdir error\n", argv[i]);
return 1;
}
}
return 0;
}
feof(),用這個函數(shù)判斷是否讀到文件尾了。
fread(buf,size,count,fp);//buf輸入數(shù)據(jù)起始地址,size 每個數(shù)據(jù)塊的大小,count 每次寫入的數(shù)據(jù)塊個數(shù),fp 文件指針
寫好后是:
while(!feof(fp))
{
fread(temp[i],sizeof(struct use),1,fp);//這個讀出來放數(shù)組里面
i++;
}
問題是你讀的是txt文件,完全可以用fscanf()函數(shù)么。
首先是最簡單的讀寫一個字符的函數(shù)fputc和fgetc,在這個基礎(chǔ)上又出現(xiàn)了putw和getw、fgets和fputs,此外還說過格式化讀寫函數(shù)fprintf和fscanf函數(shù)。
從原理上來說,只要fputc和fgetc函數(shù)基本就可以完成數(shù)據(jù)的讀寫操作了,但是在實際的使用中會遇到諸多不便,因此上面那一大堆函數(shù)就冒出來了(其實也不多)。上面函數(shù)中最方便的就是格式化讀寫函數(shù)fprintf和fscanf了,因為可以一行行的進行讀取,但是有個問題就是這兩位老人家動作比較慢,fprintf在寫文件的時候要把二進制形式表示的數(shù)據(jù)轉(zhuǎn)換為ASCII碼形式,fscanf在讀文件的時候又要將ASCII碼轉(zhuǎn)換為二進制的形式。
好不容易出來個好用的函數(shù),竟然是個慢性子,聰明的你現(xiàn)在也許就在想了:那能不能不轉(zhuǎn)換,直接讀寫二進制的數(shù)據(jù)呢?答案就是fread和fwrite,在需要頻繁進行數(shù)據(jù)讀寫的時候,使用這兩個函數(shù)將大大提升效率。
fread和fwrite函數(shù)的定義
fread(pBuffer,size,count,pFile);
fwrite(pBuffer,size,count,pFile);
要讀寫一個數(shù)據(jù)塊的話,無論是讀還是寫,都需要指定一個起始地址,讀的話從這個起始地址讀,寫的話從這個起始地址寫,上面函數(shù)定義中的第一個參數(shù)pBuffer就是用于指定這個起始地址,size讀寫的字節(jié)數(shù),count則指定讀寫多少個size大小的數(shù)據(jù),pFile是文件結(jié)構(gòu)指針。
fread和fwrite函數(shù)使用示例
說到數(shù)據(jù)塊我們自然會想到結(jié)構(gòu)體,如果一個文件中保存的是一個個結(jié)構(gòu)體信息,那每一個結(jié)構(gòu)體信息就可以看做一個數(shù)據(jù)塊了。這里直接用前面文章中我們一直使用的學生成績信息的結(jié)構(gòu)體:
C語言: 知蟻博客
struct student
{
int nID; //學號
char chName[20]; //姓名
float fScores[3]; //3門課的成績
};
實例程序有點小復雜的,首先我們自己新建一個txt文件,也就是ASCII文件啦,然后寫上一些數(shù)據(jù),如下:
1 zhangsan 78.0 79.0 80.0
2 lisi 79.0 77.0 78.0
3 wangwu 90.0 97.0 78.0
4 zhaokai 56.0 57.0 58.0
我們先用ASCII方式打開這個文件,通過fscanf函數(shù)讀取里面的數(shù)據(jù),然后通過fwrite寫入到新的二進制格式的文件中,這樣我們就得到了一個保存上面信息的二進制格式的文件了,下面就是通過fread函數(shù)進行數(shù)據(jù)的讀取了。(記住:fread和fwrite一般用于二進制文件的輸入輸出,ASCII文件還是不要考慮了)。
C++語言: 知蟻博客
#include "stdio.h"
struct student
{
int nID; //學號
char chName[20]; //姓名
float fScores[3]; //3門課的成績
};
void main()
{
FILE *pRead,*pWrite;
struct student tStu[4];
struct student *ptStu = NULL;
int nCount = 0;
//ASCII方式打開文件 用于讀入
pRead=fopen("stu_scores.txt","r");
if(NULL == pRead)
{
return;
}
//二進制文件打開文件 用于寫入
pWrite=fopen("stu_scores_bin.txt","wb");
if(NULL == pWrite)
{
fclose(pRead);
return;
}
//fscanf讀取數(shù)據(jù),fwrite寫入數(shù)據(jù)
ptStu = tStu;
while(!feof(pRead))
{
fscanf(pRead,"%d %s %f %f %f\n",ptStu-nID,ptStu-chName,ptStu-fScores[0],ptStu-fScores[1],ptStu-fScores[2]);
fwrite(ptStu,sizeof(struct student),1,pWrite);
printf("%d %s %.1f %.1f %.1f\n",ptStu-nID,ptStu-chName,ptStu-fScores[0],ptStu-fScores[1],ptStu-fScores[2]);
ptStu++;
}
fclose(pRead);
fclose(pWrite);
memset(tStu,0×00,sizeof(tStu)); //清空數(shù)據(jù)
//二進制文件打開文件 用于讀取
pRead=fopen("stu_scores_bin.txt","rb");
if(NULL == pRead)
{
printf("open file stu_scores_bin.txt failed");
return;
}
//下面有兩種fread的讀數(shù)據(jù)方式,將下面的1換成0,則使用第二種方式
#if 1
//一條條的讀取
ptStu = tStu;
nCount = fread(ptStu,sizeof(struct student),1,pRead);
while(nCount0)
{
printf("%d %s %.1f %.1f %.1f\n",ptStu-nID,ptStu-chName,ptStu-fScores[0],ptStu-fScores[1],ptStu-fScores[2]);
ptStu++;
nCount = fread(ptStu,sizeof(struct student),1,pRead);
}
#else
//因為事先知道有4條信息,因此可以直接讀取四條信息
fread(tStu,sizeof(struct student),4,pRead);
for(nCount=0; nCount4; nCount++)
{
printf("%d %s %.1f %.1f %.1f\n",tStu[nCount].nID,tStu[nCount].chName,tStu[nCount].fScores[0],tStu[nCount].fScores[1],tStu[nCount].fScores[2]);
}
#endif
fclose(pRead);
}
上面用fread讀取的時候,我們既可以一條條的讀取,也可以一次讀入多條,這就是為什么參數(shù)中有size和count的原因
#include sys/wait.h
#include assert.h
#include stdio.h
#include stdlib.h
#include unistd.h
#include string.h
int main(int argc, char *argv[])
{
int pfd[2];
pid_t cpid;
char buf;
assert(argc == 2);
if (pipe(pfd) == -1)
{
perror("pipe");
exit(EXIT_FAILURE);
}
//創(chuàng)建子進程
cpid = fork();
if (cpid == -1)
{
//創(chuàng)建子進程失敗
perror("fork"); exit(EXIT_FAILURE);
}
if (cpid == 0)
{ /* 子進程中讀取管道里面讀數(shù)據(jù) */
close(pfd[1]); /* 關(guān)閉不使用的管道寫入端 */
while (read(pfd[0], buf, 1) 0)
{
write(STDOUT_FILENO, buf, 1);//在標準的輸出設(shè)備上輸出讀取管到的內(nèi)容
}
write(STDOUT_FILENO, "\n", 1);
close(pfd[0]);
_exit(EXIT_SUCCESS);
}
else
{ /* 父進程將參數(shù) argv[1]字符串 寫入管道 */
close(pfd[0]); /* 關(guān)閉不使用的管道讀取端 */
write(pfd[1], argv[1], strlen(argv[1]));
close(pfd[1]); /* 關(guān)閉管道寫入端,此時讀取端就會收到 EOF 標志*/
wait(NULL); /* 等待子進程運行結(jié)束 */
exit(EXIT_SUCCESS);
}
}
函數(shù)調(diào)用嚴重有問題,求#include"cipan.h"里面的詳細內(nèi)容,單看函數(shù)readdisk()的話沒啥問題