姓名 编号 年龄
因为不同的写入方式,就有不同的读取方式,我把这行字略了,文件内容:
张三 0105 34
李四 0106 33
王五 0107 32
以下是我的标准程序:
注意messgetxt文件和C文件要在同一目录下
#include<stdioh>
#define ST (struct Student)malloc(sizeof(struct Student))
typedef struct Student
{
char num[5];
char name[10];
int ho;
struct Student next;
}SS;
SS Readstu(SS head);//读取
void display(SS head);//打印
void Writestu(SS head);//写入
SS min(SS head);//排序
SS Readstu(SS head)
{
SS p1,p2=head;
FILE fp;
fp=fopen("messgetxt","rb");
if(fp==NULL)printf("文件无法打开!\n");
else
{
//rewind(fp);
p1=ST;
while(!feof(fp))
{
//fread(p1,sizeof(SS),1,fp);
fscanf(fp,"%s %s %d\n",p1->name,&p1->num,&p1->ho);
if(head==NULL)head=p1;
p2=p1;
if(!feof(fp))p1=ST;
else p1=NULL;
p2->next=p1;
}
//free(p1);
//p1=NULL;
}
fclose(fp);
return(head);
}
void Writestu(SS head)
{
SS p1=head;
FILE fp;
fp=fopen("messgetxt","wb");
if(fp==NULL)printf("文件无法打开!\n");
else{
while(p1!=NULL)
{
fprintf(fp,"%s %s %d\n",p1->name,p1->num,p1->ho);
p1=p1->next;
}
}
fclose(fp);
}
//主函数
int main()
{
SS head=NULL;
head=Readstu(head);
printf(" \n -------By心离\n");
display(head);
head=min(head);
printf("排序后\n");
display(head);
Writestu(head);
return 0;
}
void display(SS head)
{
SS p;
p=head;
printf("名字\t编号\t年龄\n");
while(p!=NULL)
{
printf("%s\t%s\t%d\n",p->name,p->num,p->ho);
p=p->next;
}
}
SS min(SS head)
{
SS first;
SS tail;
SS min_p;
SS min;
SS p;
first=NULL;
while(head!=NULL)
{
for(p=head,min=head;p->next;p=p->next)
{
if(p->next->ho<min->ho)
{
min_p=p;
min = p->next;
}
}
if(first == NULL)
{
first = min;
tail = min;
}
else
{
tail->next=min;
tail=min;
}
if(min == head)
{
head = head->next;
}
else
{
min_p->next = min->next;
}
}
if(first != NULL)
{
tail->next = NULL;
}
head = first;
return(head);
}
输出:王五 0107 32
李四 0106 33
张三 0105 34
可能在文件看不到换行,这个没关系,一样可以重复读取
C语言文件 *** 作函数
1,两种文件存取方式(输入,输出方式)
顺序存取
直接存取
2,数据的两种存放形式
文本文件
二进制文件
132文件指针
定义文件类型指针变量的一般形式:
FILE 指针变量名;
例如:
FILE fp1,fp2;
133打开文件
在使用文件之前,需打开文件在C里使用fopen函数打开文件格式为:
fopen(文件名,文件使用方式);
此函数返回一个指向FILE类型的指针如:
FILE fp;
fp=fopen("file_1","r");
如果调用成功,fp就指向file_1,否则返回为NULL,所以为了保证文件的正确使用,要进行测试采用如下语句:
If((fp=fopen("file_1","r"))==NULL)
{
printf("Cannot open this file\n");
exit(0);
}
134关闭文件
当文件的读写 *** 作完成之后,使用fclose函数关闭文件格式如下:
fclose(文件指针)
如:fclose(fp);
135调用getc(fgetc)和putc(fputc)函数进行输入和输出
1,调用putc(或fputc)函数输出一个字符
调用形式为:
putc(ch,fp);
功能是:将字符ch写到文件指针fp所指的文件中去当输出成功,putc函数返回所输出的字符;否则,返回一个EOF值EOF是在stdioh库
函数文件中定义的符号常量,其值等于-1
135调用getc(fgetc)和putc(fputc)函数进行输入和输出
例如:把从键盘输入的文本按原样输出到名为file_1dat文件中,用字符@作为键盘输入结束标志
#include
Void main()
{
FILE fpout;
char ch;
if(fpout=fpopen("file_1","w")==NULL)
{
printf("Cannot open this file!\n");
exit(0);
}
ch=getchar();
while(ch!='@')
{ fputc(ch,fpout); ch=getchar(); }
fclose(fpout);
}
2调用getc(或fgetc)函数输入一个字符
调用形式为:
ch=getc(pf);
功能是:从pf指定的文件中读如一个字符,并把它作为函数值返回
例如:把一个已存在磁盘上的file_1dat文本文件中的内容,原样输出到终端屏幕上
#include
void main(){
FILE fpin;
char ch;
if((fpin=fopen("file_1dat","r"))==NULL)
{ printf("Cann't open this file!\n");exit(0);}
ch=fgetc(fpin);
while (ch!=EOF)
{ putchar(ch); ch=fgetc(fpin);}
fclose(fpin);
}
136判断文件结束函数feof
EOF可以作为文本文件的结束 标志,但不能作为二进制文件的结束符feof函数既可以判断二进制文件,又可以判断文本文件
例:编写程序,用于把一个文本文件(源)复制到另一个文件(目的)中,源文件名和目的文件名由命令行输入命令形式如下:
可执行程序名 源文件名 目的文件名
#include
void filecopy(FILE ,FILE );
void main(int argc,char argv[]){
FILE fpin,fpout;
if(argc==3)
{ fpin=fopen(argv[1],"r");
fpout=fopen(argv[2],"w");
filecopy(fpin,fpout);
fclose(fpin);fclose(fpout);
}
else if(argc>3)
printf("The file names too many!!\n";
else
printf("There are no file names for input or output!!\n );
}
void filecopy(FILE fpin,FILE fpout)
{
char ch;
ch=getc(fpin);
while(!feof(fpin))
{putc(ch,fpout); ch=getc(fpin);}
}
137fscanf函数和fprintf函数
1,fscanf函数
fscanf只能从文本文件中按格式输入,和scanf函数相似,只不过输入的对象是磁盘上文本文件中的数据调用形式为:
fscanf(文件指针,格式控制字符串,输入项表)
例如:fscanf(fp,"%d%d",&a,&b);
fscanf(stdin,"%d%d",&a,&b);
等价于scanf("%d%d",&a,&b);
3fprintf函数
fprintf函数按格式将内存中的数据转换成对应的字符,并以ASCII代码形式输出到文本文件中Fprintf函数和printf函数相似,只是
将输出的内容按格式存放到磁盘的文本文件中调用形式如下:
fprintf(文件指针,格式控制字符串,输出项表)
如:fprintf(fp,"%d %d",x,y);
以下语句 fprintf(stdout,"%d %d",x,y)
138fgets函数和fputs函数
1,fgets函数
fgets函数用来从文件中读入字符串调用形式如下:
fgets(str,n,fp);
函数功能是:从fp所指文件中读入n-1个字符放入str为起始地址的空间内;如果在未读满n-1个字符时,则遇到换行符或一个EOF结束本次读 *** 作,
并已str作为函数值返回
138fgets函数和fputs函数
2,fputs函数
fput函数把字符串输出到文件中函数调用形式如下:
fputs(str,fp);
注意:为了便于读入,在输出字符串时,应当人为的加诸如"\n"这样的字符串
139fread函数和fwrite函数
fread and fwrite函数用来读,写二进制文件它们的调用形式如下:
fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);
buffer:要输入或输出的数据块的首地址
count:每读写一次,输入或输出数据块的个数
size:每个数据块的字节数
fp:文件指针
139fread函数和fwrite函数
例如有如下结构体:
struct st{
char num[8];
float mk[5];
}pers[30];
以下循环将把这30个元素中的数据输出到fp所指文件中
for(i=0;i<30;i++)
fwrite(&pers[i],sizeof(struct st),1,fp);
139fread函数和fwrite函数
以下语句从fp所指的文件中再次将每个学生数据逐个读入到pers数组中
i=0;
fread(&pers[i],sizeof(struct st),1,fp);
while(!feof(fp))
{ i++;
fread(&pers[i],sizeof(struct st),1,fp);
}
1310文件定位函数
1,fseek函数
fseek函数用来移动文件位置指针到指定的位置上,接着的读或写 *** 作将从此位置开始函数的调用形式如下:
fseek(pf,offset,origin)
pf:文件指针
offset:以字节为单位的位移量,为长整形
origin:是起始点,用来指定位移量是以哪个位置为基准的
1,fseek函数
位移量的表示方法
标识符 数字 代表的起始点
SEEK_SET 0 文件开始
SEEK_END 2 文件末尾
SEEK_CUR 1 文件当前位置
假设pf已指向一个二进制文件,则;
fseek(pf,30L,SEEK_SET)
fseek(pf,-10Lsizeof(int),SEEK_END)
对于文本文件,位移量必须是0;如:
fseek(pf,0L,SEEK_SET)
fseek(pf,0L,SEEK_END)
2 ftell函数
ftell函数用以获得文件当前位置指针的位置,函数给出当前位置指针相对于文件开头的字节数如;
long t;
t=ftell(pf);
当函数调用出错时,函数返回-1L
我们可以通过以下方式来测试一个文件的长度:
fseek(fp,0L,SEEK_END);
t=ftell(fp);
3rewind函数
调用形式为:
rewind(pf);
函数没有返回值函数的功能是使文件的位置指针回到文件的开头
最常用的文件使用方式及其含义如下:
2,"rb"为读而打开二进制文件
4,"wb"为写而打开二进制文件
6,"ab"为在文件后面添加数据而打开一个二进制文件
8,"rb+"为读和写而打开二进制文件只是在随后的读写时,可以由位置函数设置读和写的起始位置
9,"w+"首先建立一个新文件,进行写 *** 作,随后可以从头开始读(若文件存在,原内容将全部消失)
10,"wb+"功能与"w+"同只是在随后的读写时,可以由位置函数设置读和写的起始位置
11,"a+"功能与"a"相同;只是在文件尾部添加新的数据后,可以从头开始读
12,"ab+"功能与"a+"相同;只是在文件尾部添加新数据之后,可以由位置函数设置开始读的起始位置
1,"r"为读而打开文本文件(不存在则出错)
3,"w"为写而打开文本文件(若不存在则新建,反之,则从文件起始位置写,原内容将被覆盖)
5,"a"为在文件后面添加数据而打开文本文件(若不存在,则新建;反之,在原文件后追加)
7,"r+"为读和写而打开文本文件(读时,从头开始;在写数据时,新数据只覆盖所占的空间,其后不变)
读取的代码方式如下:
intmain()
{
longfile;
struct_finddata_tfind;
_chdir("d:\\");
if((file=_findfirst("",&find))==-1L)
{
printf("空白!\n");
exit(0);
}
printf("%s\n",findname);
while(_findnext(file,&find)==0)
{
printf("%s\n",findname);
}
_findclose(file);
return0;
}
用C语言读取目录中的文件名的方法:
1、如果是在window环境下,可以用一下方法:
使用stdlibh头文件声明的system()函数,调用系统命令dir,把c:目录下文件列表写入文件dirtxt中
2、使用direnth头文件中声明的opendir(),readdir()函数;
3、如果没有direnth,可以使用ioh头文件中声明的_findfirst(),_findnext()函数:
这篇文章主要介绍了C/C++ 监控磁盘与目录 *** 作的示例,帮助大家更好的理解和学习C/C++编程,感兴趣的朋友可以了解下
遍历磁盘容量:
#include <stdioh>
#include <Windowsh>
void GetDrivesType(const char lpRootPathName)
{
UINT uDriverType = GetDriveType(lpRootPathName);
switch (uDriverType)
{
case DRIVE_UNKNOWN:puts("未知磁盘"); break;
case DRIVE_NO_ROOT_DIR: puts("路径无效"); break;
case DRIVE_REMOVABLE: puts("可移动磁盘"); break;
case DRIVE_FIXED: puts("固定磁盘"); break;
case DRIVE_REMOTE: puts("网络磁盘"); break;
case DRIVE_CDROM: puts("光驱"); break;
case DRIVE_RAMDISK: puts("内存映射盘"); break;
default: break;
}
}
void GetDrivesFreeSpace(const char lpRootPathName)
{
unsigned long long available, total, free;
if (GetDiskFreeSpaceEx(lpRootPathName, (ULARGE_INTEGER)&available,
(ULARGE_INTEGER)&total, (ULARGE_INTEGER)&free))
{
printf("磁盘: %s | 总计: %lld MB 已用: %lld MB 剩余: %lld MB \n",
lpRootPathName, total >> 20, available >> 20, free >> 20);
}
}
int main(int argc,char argv[])
{
DWORD dwSize = MAX_PATH;
char szLogicalDrives[MAX_PATH] = {0};
// 获取逻辑驱动器号字符串
DWORD dwResult = GetLogicalDriveStringsA(dwSize, szLogicalDrives);
if (dwResult > 0 && dwResult <= MAX_PATH) {
char szSingleDrive = szLogicalDrives; // 从缓冲区起始地址开始
while (szSingleDrive) {
//printf("Drive: %s\n", szSingleDrive); // 输出单个驱动器的驱动器号
// GetDrivesType(szSingleDrive);
GetDrivesFreeSpace(szSingleDrive);
szSingleDrive += strlen(szSingleDrive) + 1; // 获取下一个驱动器地址
}
}
system("pause");
return 0;
}
遍历文件特定路径:
循环遍历文件路径,并将文件后缀为exe的路径筛选出来
#include <stdioh>
#include <windowsh>
#include <tlhelp32h>
void SearchFile(char pszDirectory)
{
// 搜索指定类型文件
char pszFileName = NULL;
char pTempSrc = NULL;
WIN32_FIND_DATA FileData = { 0 };
// 申请动态内存
pszFileName = new char[2048];
pTempSrc = new char[2048];
// 构造搜索文件类型字符串 表示搜索所有文件类型
wsprintf(pszFileName, "%s\\", pszDirectory);
HANDLE hFile = ::FindFirstFile(pszFileName, &FileData);
if (INVALID_HANDLE_VALUE != hFile)
{
do
{
// 过滤掉当前目录"" 和上一层目录""
if ('' == FileDatacFileName[0])
continue;
// 拼接文件路径
wsprintf(pTempSrc, "%s\\%s", pszDirectory, FileDatacFileName);
// 判断是否是目录还是文件
if (FileDatadwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
SearchFile(pTempSrc); // 如果是目录则继续递归
else
{
char drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
_splitpath(pTempSrc, drive, dir, fname, ext);
// 如果是文件并且后缀为exe则输出具体路径
if (strcmp(ext, "exe") == 0)
printf("%s \n", pTempSrc);
}
} while (::FindNextFile(hFile, &FileData));
}
FindClose(hFile);
delete[]pTempSrc;
delete[]pszFileName;
}
int main(int argc, char argv[])
{
SearchFile("c:\\MinGW7");
system("pause");
return 0;
}
监控文件目录变化:
#include <stdioh>
#include <windowsh>
#include <tlhelp32h>
UINT MonitorFileThreadProc(LPVOID lpVoid)
{
char pszDirectory = (char )lpVoid;
// 打开目录, 获取文件句柄
HANDLE hDirectory = CreateFile(pszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (INVALID_HANDLE_VALUE == hDirectory)
return 1;
char szFileName[MAX_PATH] = { 0 };
BOOL bRet = FALSE;
DWORD dwRet = 0;
DWORD dwBufferSize = 2048;
// 申请一个足够大的缓冲区
BYTE pBuf = new BYTE[dwBufferSize];
if (NULL == pBuf)
return 2;
FILE_NOTIFY_INFORMATION pFileNotifyInfo = (FILE_NOTIFY_INFORMATION )pBuf;
// 开始循环设置监控
do
{
RtlZeroMemory(pFileNotifyInfo, dwBufferSize);
// 设置监控目录
bRet = ReadDirectoryChangesW(hDirectory, pFileNotifyInfo, dwBufferSize, TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME | // 修改文件名
FILE_NOTIFY_CHANGE_ATTRIBUTES | // 修改文件属性
FILE_NOTIFY_CHANGE_LAST_WRITE, // 最后一次写入
&dwRet, NULL, NULL);
if (FALSE == bRet)
break;
// 将宽字符转换成窄字符,宽字节字符串转多字节字符串
WideCharToMultiByte(CP_ACP, 0, (wchar_t )(&pFileNotifyInfo->FileName),
(pFileNotifyInfo->FileNameLength / 2),szFileName,MAX_PATH,NULL,NULL);
// 将路径与文件连接成完整文件路径
char FullFilePath[1024] = { 0 };
strncpy(FullFilePath, pszDirectory, strlen(pszDirectory));
strcat(FullFilePath, szFileName);
// 判断 *** 作类型并显示
switch (pFileNotifyInfo->Action)
{
case FILE_ACTION_ADDED:
printf("文件被 [创建]: %s \n", FullFilePath); break;
case FILE_ACTION_REMOVED:
printf("文件被 [删除]: %s \n", FullFilePath); break;
case FILE_ACTION_MODIFIED:
printf("文件被 [修改]: %s \n", FullFilePath); break;
case FILE_ACTION_RENAMED_OLD_NAME:
printf("文件被 [重命名]: %s \n", FullFilePath); break;
}
} while (bRet);
CloseHandle(hDirectory);
delete[] pBuf;
pBuf = NULL;
return 0;
}
int main(int argc, char argv[])
{
char pszDirectory = "C:\\";
// 创建线程开始监控
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorFileThreadProc, pszDirectory, 0, NULL);
while (1)
{
Sleep(10000);
}
system("pause");
return 0;
}
监控目录文件变化:
可以将其改为一个简单的文件防篡改程序,也可以用来监控病毒的行为
#include <stdioh>
#include <Windowsh>
#include <tlhelp32h>
DWORD WINAPI MonitorFileThreadProc(LPVOID lParam)
{
char pszDirectory = (char )lParam;
BOOL bRet = FALSE;
BYTE Buffer[1024] = { 0 };
FILE_NOTIFY_INFORMATION pBuffer = (FILE_NOTIFY_INFORMATION )Buffer;
DWORD dwByteReturn = 0;
HANDLE hFile = CreateFile(pszDirectory, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (INVALID_HANDLE_VALUE == hFile)
return 1;
while (TRUE)
{
ZeroMemory(Buffer, sizeof(Buffer));
// 设置监控目录回调函数
bRet = ReadDirectoryChangesW(hFile,&Buffer,sizeof(Buffer),TRUE,
FILE_NOTIFY_CHANGE_FILE_NAME | // 修改文件名
FILE_NOTIFY_CHANGE_ATTRIBUTES | // 修改文件属性
FILE_NOTIFY_CHANGE_LAST_WRITE, // 最后一次写入
&dwByteReturn, NULL, NULL);
if (TRUE == bRet)
{
char szFileName[MAX_PATH] = { 0 };
// 将宽字符转换成窄字符,宽字节字符串转多字节字符串
WideCharToMultiByte(CP_ACP,0,pBuffer->FileName,(pBuffer->FileNameLength / 2),
szFileName,MAX_PATH,NULL,NULL);
// 将路径与文件连接成完整文件路径
char FullFilePath[1024] = { 0 };
strncpy(FullFilePath, pszDirectory, strlen(pszDirectory));
strcat(FullFilePath, szFileName);
switch (pBuffer->Action)
{
case FILE_ACTION_ADDED:
{
printf("添加: %s \n", FullFilePath); break;
}
case FILE_ACTION_REMOVED:
{
printf("删除: %s \n", FullFilePath); break;
}
case FILE_ACTION_MODIFIED:
{
printf("修改: %s \n", FullFilePath); break;
}
case FILE_ACTION_RENAMED_OLD_NAME:
{
printf("重命名: %s", szFileName);
if (0 != pBuffer->NextEntryOffset)
{
FILE_NOTIFY_INFORMATION tmpBuffer = (FILE_NOTIFY_INFORMATION )
((DWORD)pBuffer + pBuffer->NextEntryOffset);
switch (tmpBuffer->Action)
{
case FILE_ACTION_RENAMED_NEW_NAME:
{
ZeroMemory(szFileName, MAX_PATH);
WideCharToMultiByte(CP_ACP,0,tmpBuffer->FileName,
(tmpBuffer->FileNameLength / 2),
szFileName,MAX_PATH,NULL,NULL);
printf(" -> %s \n", szFileName);
break;
}
}
}
break;
}
case FILE_ACTION_RENAMED_NEW_NAME:
{
printf("重命名(new): %s \n", FullFilePath); break;
}
}
}
}
CloseHandle(hFile);
return 0;
}
int main(int argc, char argv[])
{
char pszDirectory = "C:\\";
HANDLE hThread = CreateThread(NULL, 0, MonitorFileThreadProc, pszDirectory, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
return 0;
}
以上就是C/C++ 监控磁盘与目录 *** 作的示例的详细内容
以上就是关于求帮忙一个C语言IO问题,谢谢!!全部的内容,包括:求帮忙一个C语言IO问题,谢谢!!、C语言的磁盘文件问题、C语言怎么读取某一文件夹下的所有文件夹和文件等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)