C语言学习之路(基础篇)—— 文件操作(下)

news2024/9/21 2:36:19

说明:该篇博客是博主一字一码编写的,实属不易,请尊重原创,谢谢大家!

文件的随机读写

1) fseek

  • 表头文件:#include <stdio.h>
  • 定义函数:int fseek(FILE *stream, long offset, int whence);
  • 功能:移动文件流(文件光标)的读写位置。
  • 参数:
    stream:已经打开的文件指针
    offset:根据whence来移动的位移数(偏移量),可以是正数,也可以负数,如果正数,则相对于whence往右移动,如果是负数,则相对于whence往左移动。如果向前移动的字节数超过了文件开头则出错返回,如果向后移动的字节数超过了文件末尾,再次写入时将增大文件尺寸。
    whence:其取值如下:
    SEEK_SET:从文件开头移动offset个字节
    SEEK_CUR:从当前位置移动offset个字节
    SEEK_END:从文件末尾移动offset个字节
  • 返回值:
    成功:0
    失败:-1

示例1: SEEK_SET:从文件开头移动offset个字节(会覆盖原有位置上的字符)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int main()
{
	FILE* fp = fopen("fseek.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	// 移动光标前写入
	fputs("hellocdtaogang", fp);
	int res = fseek(fp, 0, SEEK_SET); // 文件开头位置
	if (!res)
	{
		printf("从文件开头位置移动文件光标0个字节!");
	}
	// 移动光标后写入
	fputs("fseek", fp);
	fclose(fp);

	return 0;
}

在这里插入图片描述

示例2: SEEK_END:从文件末尾移动offset个字节(会覆盖原有位置上的字符)

int main()
{
	FILE* fp = fopen("fseek.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	// 移动光标前写入
	fputs("hellocdtaogang", fp);
	int res = fseek(fp, 0, SEEK_SET); // 文件开头位置
	if (!res)
	{
		printf("从文件开头位置移动文件光标0个字节!\n");
	}
	// 移动光标后写入
	fputs("fseek", fp);
	
	res = fseek(fp, -9, SEEK_END); // 文件开头位置
	if (!res)
	{
		printf("从文件开头位置移动文件光标向左9个字节!");
	}
	// 移动光标后写入
	fputs("CSDN:cdtaogang", fp);
	fclose(fp);
	return 0;
}

在这里插入图片描述

示例3: SEEK_END:从当前位置移动offset个字节(会覆盖原有位置上的字符)

int main()
{
	FILE* fp = fopen("fseek.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	// 移动光标前写入
	fputs("hellocdtaogang", fp);
	int res = fseek(fp, 0, SEEK_SET); // 文件开头位置
	if (!res)
	{
		printf("从文件开头位置移动文件光标0个字节!\n");
	}
	// 移动光标后写入
	fputs("fseek", fp);
	
	res = fseek(fp, -9, SEEK_END); // 文件结尾位置向左移动9个字节
	if (!res)
	{
		printf("从文件开头位置移动文件光标向左9个字节!\n");
	}
	// 移动光标后写入
	fputs("CSDN:cdtaogang", fp);
	res = fseek(fp, -14, SEEK_CUR); // 文件当前位置向左移动14个字节
	if (!res)
	{
		printf("从文件当前位置移动文件光标向左14个字节!");
	}
	// 移动光标后写入
	fputs("hello", fp);
	fclose(fp);
	return 0;
}

在这里插入图片描述

2) rewind

  • 表头文件:#include <stdio.h>
  • 定义函数:void rewind(FILE *stream);
  • 功能:把文件流(文件光标)的读写位置移动到文件开头;就相当于fseek(fp, 0, SEEK_SET);一样效果
  • 参数:
    stream:已经打开的文件指针
  • 返回值:
    无返回值

示例: 把文件光标的读写位置移动到文件开头

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int main()
{
	FILE* fp = fopen("rewind.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	// 移动光标前写入
	fputs("nnnnncdtaogang", fp);
	rewind(fp); // 把文件光标的读写位置移动到文件开头
	// 移动光标后写入
	fputs("hello", fp);

	return 0;
}

在这里插入图片描述

3) ftell

  • 表头文件:#include <stdio.h>
  • 定义函数:long ftell(FILE *stream);
  • 功能:获取文件流(文件光标)的读写位置。
  • 参数:
    stream:已经打开的文件指针
  • 返回值:
    成功:当前文件流(文件光标)的读写位置
    失败:-1

示例: 获取文件流(文件光标)的读写位置,同时也可以根据返回值测试出该文件有多少个字符(字节)

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int main()
{
	FILE* fp = fopen("rewind.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	// 移动光标前写入
	fputs("nnnnncdtaogang", fp);
	rewind(fp); // 把文件光标的读写位置移动到文件开头
	// 移动光标后写入
	fputs("hello", fp);
	// 获取文件流(文件光标)的读写位置
	int location = ftell(fp);
	printf("location = %d\n", location); // 5  也就是文件光标在写入hello的字符长度的位置
	// 获取文件的字符长度(大小)
	fseek(fp, 0, SEEK_END); // 文件末尾
	int count = ftell(fp);
	printf("count = %d\n", count);
	// 关闭文件
	fclose(fp);

	return 0;
}

在这里插入图片描述

获取文件状态

stat

  • 表头文件1:#include <sys/types.h>
  • 表头文件2:#include <sys/stat.h>
  • 定义函数:int stat(const char *path, struct stat *buf);
  • 功能:获取文件状态信息
  • 参数:
    path:文件名
    buf:保存文件信息的结构体
  • 返回值:
    成功:0
    失败:-1

struct stat内各参数的说明:

struct stat {
	dev_t         st_dev;         //文件的设备编号
	ino_t         st_ino;          //节点
	mode_t        st_mode;   //文件的类型和存取的权限
	nlink_t       st_nlink;     //连到该文件的硬连接数目,刚建立的文件值为1
	uid_t         st_uid;         //用户ID
	gid_t         st_gid;         //组ID
	dev_t         st_rdev;      //(设备类型)若此文件为设备文件,则为其设备编号
	off_t         st_size;        //文件字节数(文件大小)
	unsigned long st_blksize;   //块大小(文件系统的I/O 缓冲区大小)
	unsigned long st_blocks;    //块数
	time_t        st_atime;     //最后一次访问时间
	time_t        st_mtime;    //最后一次修改时间
	time_t        st_ctime;     //最后一次改变时间(指属性)
};

示例1: 使用stat函数判断文件是否存在

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>


int main()
{
	struct stat buf;
	int res = 0;
	res = stat("stat.txt", &buf);
	// 根据stst返回值可以判断文件是否存在,存在返回0, 不存在返回-1
	if (!res)
	{
		printf("stat.txt file found");
	}
	else
	{
		printf("stat.txt file not found");
	}

	return 0;
}

在这里插入图片描述

示例2: 使用stat函数判断文件是否存在,存在则返回文件大小

int main()
{
	struct stat buf;
	int res = 0;
	res = stat("stat.txt", &buf);
	// 根据stst返回值可以判断文件是否存在,存在返回0, 不存在返回-1
	if (!res)
	{
		printf("stat.txt file found");
	}
	else
	{
		printf("stat.txt file not found\n");
	}
	// 使用`stat`函数判断rewind.txt文件是否存在,存在则返回文件大小
	res = stat("rewind.txt", &buf);
	if (!res)
	{
		// rewind.txt文件存在,返回文件大小
		int buffer_size = buf.st_size;
		printf("rewind.txt file size:%d字节", buffer_size);
	}
	else
	{
		printf("stat.txt file not found");
	}
	return 0;
}

在这里插入图片描述

Windows和Linux文本文件区别

  • b是二进制模式的意思,b只是在Windows有效,在Linuxrrb的结果是一样的
  • UnixLinux下所有的文本文件行都是\n结尾,而Windows所有的文本文件行都是\r\n结尾
  • Windows平台下,以 文本 方式打开文件,不加b
  • 当读取文件的时候,系统会将所有的 “\r\n” 转换成 “\n
  • 当写入文件的时候,系统会将 “\n” 转换成 “\r\n” 写入
  • 二进制 方式打开文件,则读\写都不会进行这样的转换
  • Unix/Linux平台下, 文本 二进制 模式没有区别,“\r\n” 作为两个字符原样输入输出

在这里插入图片描述

判断文本文件是Linux格式还是Windows格式:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>


int main(int argc, char** args)
{
	if (argc < 2)
		return 0;

	FILE* p = fopen(args[1], "rb");
	if (!p)
		return 0;

	char a[1024] = { 0 };
	fgets(a, sizeof(a), p);

	int len = 0;
	while (a[len])
	{
		if (a[len] == '\n')
		{
			if (a[len - 1] == '\r')
			{
				printf("windows file\n");
			}
			else
			{
				printf("linux file\n");
			}
		}
		len++;
	}

	fclose(p);

	return 0;

设置运行命令参数:右击项目-属性-调试

在这里插入图片描述

运行代码查看结果

在这里插入图片描述

删除文件、重命名文件名

1) 删除文件

  • 表头文件:#include <stdio.h>
  • 定义函数:int remove(const char *pathname);
  • 功能:删除文件
  • 参数:
    pathname:文件名
  • 返回值:
    成功:0
    失败:-1

示例: 使用remove函数删除文件,并根据返回值判断是否删除成功

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int main()
{	
	char* fileName = "remove.txt";
	FILE* fp = fopen(fileName, "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	// 关闭文件
	fclose(fp);
	// 删除文件
	int res = 0;
	res = remove(fileName);
	if (!res)
	{
		printf("%s 文件删除成功!", fileName);
	}


	return 0;
}

2) 重命名文件名

  • 表头文件:#include <stdio.h>
  • 定义函数:int rename(const char *oldpath, const char *newpath);
  • 功能:把oldpath的文件名改为newpath
  • 参数:
    oldpath:旧文件名
    newpath:新文件名
  • 返回值:
    成功:0
    失败: -1

示例: 使用rename函数对文件进行重命名,并根据返回值判断是否重命名成功

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int main()
{
	int res = 0;
	res = rename("hellocdtaogang.txt", "cdtaogang.txt");
	if (!res)
	{
		printf("重命名成功!");
	}

	return 0;
}

在这里插入图片描述

文件缓冲区

1) 概述

缓冲区:就是内存中的一块临时的空间。

ANSI C标准采用 缓冲文件系统 处理数据文件。

所谓缓冲文件系统是指系统自动地在内存区为程序中每一个正在使用的文件开辟一个文件缓冲区从内存向磁盘输出数据必须先送到内存中的缓冲区,装满缓冲区后才一起送到磁盘去。

如果从磁盘向计算机读入数据,则一次从磁盘文件将一批数据输入到内存缓冲区(充满缓冲区),然后再从缓冲区逐个地将数据送到程序数据区(给程序变量) 。

2) 磁盘文件的存取

在这里插入图片描述

  • 磁盘文件,一般保存在硬盘、U盘等掉电不丢失的磁盘设备中,在需要时调入内存
  • 在内存中对文件进行编辑处理后,保存到磁盘中
  • 程序与磁盘之间交互,不是立即完成,系统或程序可根据需要设置缓冲区,以提高存取效率

3) 更新缓冲区

  • 表头文件:#include <stdio.h>
  • 定义函数:int fflush(FILE *stream);
    功能:更新缓冲区,让缓冲区的数据立马写到文件中。
    参数:
    stream:文件指针
    返回值:
    成功:0
    失败:-1

在这里插入图片描述

示例1: 使用fputs函数对文件进行数据写入,通过死循环让程序假死状态下来查看文件是否被写入数据,如果没有被写入数据,说明数据被存到了缓冲区。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>


int main()
{
	FILE* fp = fopen("demo.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	fputs("hellocdtaogang", fp); // 不会马上写入文件,先存至缓冲区
	while (1);
	
	return 0;
}

在这里插入图片描述

此时如果ctrl+c关闭程序,那么缓冲区将被释放

在这里插入图片描述

示例2: 调用fflush函数来强制刷新缓冲区到文件中

int main()
{
	FILE* fp = fopen("demo.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	fputs("CSDN:cdtaogang", fp); // 不会马上写入文件,先存至缓冲区
	// 调用fflush函数来强制刷新缓冲区内容到fp里面
	fflush(fp);
	while (1);

	return 0;
}

在这里插入图片描述

示例3: 当缓冲区内容满了,也会写入文件

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


int main()
{
	FILE* fp = fopen("demo.txt", "w");
	if (NULL == fp)
	{
		perror("open file fail");
		return -1;
	}
	//fputs("CSDN:cdtaogang", fp); // 不会马上写入文件,先存至缓冲区
	// 调用fflush函数来强制刷新缓冲区
	//fflush(fp);
	char buf[1024];
	memset(buf, '1', sizeof(buf));
	for (int i = 0; i < 1024; i++)
	{
		fwrite(buf, 1, sizeof(buf), fp);
		printf("i=%d", i);
	}
	while (1);

	return 0;
}

在这里插入图片描述

4) 文件缓冲区问题

  1. windows下标准输出stdout文件是没有缓冲区的,但是在linux有,比如printf中没有\n是不会显示在终端上的
  2. 标准输入stdin不能调用fflush强制刷新

快译通案例

1) 基础版1.0

  • hello:你好
  • world :世界
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


typedef struct _dict
{

	char key[256];
	char content[256];


}DICT;

void dict_init(DICT** tmp)
{
	
	DICT* p;
	// 结构体指针申请两个DICT结果体大小的空间
	p = malloc(sizeof(DICT) * 2);
	// 给p指向的结构体进行初始化
	strcpy(p[0].key, "hello");
	strcpy(p[0].content, "你好");
	strcpy(p[1].key, "world");
	strcpy(p[1].content, "世界");
	// 修改实参dict的值
	*tmp = p;
	return;
}

int search_dict_key(char* cmd, DICT* dict, int n, char* content)
{
	for (int i = 0; i < n; i++)
	{	
		// 比较终端输入的字符串与结构体中的key是否相同, 相同则将key对应的content字符串内容拷贝到形参content所指的地址
		if (strcmp(cmd, dict[i].key) == 0) 
		{
			strcpy(content, dict[i].content);
			return 1;
		
		}
	}
	// 没有找到返回
	return 0;
}

int main() 
{	
	DICT* dict = NULL;
	// 结果体初始化数据
	dict_init(&dict);
	char cmd[256];
	char content[256];
	int res = 0;
	while (1)
	{
		// 获取用户输入
		printf("请输入需要翻译的单词:");
		fgets(cmd, sizeof(cmd), stdin);
		// 去掉输入的最后一个字符\n
		cmd[strlen(cmd) - 1] = 0;
		// 搜索判断
		res = search_dict_key(cmd, dict, 2, content);
		if (res == 0)
		{
			printf("not found %s key\n", cmd);
		}
		else
		{
			printf("翻译结果为:%s\n", content);
		}

	}


	return 0;
}

在这里插入图片描述

在这里插入图片描述

2) 基础版2.0

typedef struct _dict
{

	/*char key[256];
	char content[256];*/
	char* key;
	char* content;
}DICT;

void dict_init(DICT** tmp)
{
	
	DICT* p;
	// 结构体指针申请两个DICT结果体大小的空间
	p = malloc(sizeof(DICT) * 2);
	// 给p指向的结构体进行初始化
	p[0].key = malloc(sizeof("hello") + 1);  // 为了包含\n字符所以要+1
	p[0].content = malloc(sizeof("你好"));
	strcpy(p[0].key, "hello"); // 将"hello"存p[0].key指向的空间
	strcpy(p[0].content, "你好");
	p[1].key = malloc(sizeof("world") + 1);
	p[1].content = malloc(sizeof("世界"));
	strcpy(p[1].key, "world");
	strcpy(p[1].content, "世界");
	// 修改实参dict的值
	*tmp = p;
	return;
}

在这里插入图片描述

在这里插入图片描述

3) 加强版

从英汉词典文本中读取

在这里插入图片描述

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_NUM 111102 // 一共222204行,包括原文和译文,每次读两行,所以只要111102行
#define FILENAME "dict.txt"


typedef struct _dict
{
	char* key;
	char* content;
}DICT;

FILE* open_file()
{

	FILE* fp = fopen(FILENAME, "r");
	if (NULL == fp)
	{
		perror("open file error");
		return NULL;
	}
	return fp;

}

void filter_buf(char* buf)
{	
	// buf最后一个字符下标
	int n = strlen(buf) - 1;
	// 从buf最后一个字符开始往前判断是否存在空格、\n、\r、\t,如果存在则下标-1,如#abc\r\t 跳出循环时,下标为c字符的下标
	while (buf[n] == " " || buf[n] == '\n' || buf[n] == "\r" || buf[n] == "\t")
	{
		n--;
	}
	// n+1表示有效字符后面的无效字符置为0即可,如#abc\r\t\n -> abc0
	buf[n + 1] = 0;


}

void dict_init(DICT** tmp)
{
	
	DICT* p;
	// 结构体指针申请LINE_NUM个DICT结果体大小的空间
	p = malloc(sizeof(DICT) * LINE_NUM);
	int i = 0;
	char* q = NULL;
	char buf[256];
	FILE* fp = open_file(); // 打开dict.txt文件
	while (1)
	{
		q = fgets(buf, sizeof(buf), fp);  // 读取一行数据 即原文
		if (NULL == q)
		{
			break;
		}

		filter_buf(buf); // 过滤掉单词后面的隐藏的字符如\r \t \n等
		p[i].key = malloc(strlen(buf) + 1);  // 给存储单词p[i].key开辟空间
		strcpy(p[i].key, buf + 1); // buf+1 取#后面的原文
		q = fgets(buf, sizeof(buf), fp);  // 读取一行数据 即译文
		p[i].content = malloc(strlen(buf) + 1);
		strcpy(p[i].content, buf + 6);  // buf+6取Trans:后面的译文
		i++;
	}
	
	// 修改实参dict的值
	*tmp = p;
	return;
}

int search_dict_key(char* cmd, DICT* dict, int n, char* content)
{
	for (int i = 0; i < n; i++)
	{	
		// 比较终端输入的字符串与结构体中的key是否相同, 相同则将key对应的content字符串内容拷贝到形参content所指的地址
		if (strcmp(cmd, dict[i].key) == 0) 
		{
			strcpy(content, dict[i].content);
			return 1;
		
		}
	}
	// 没有找到返回
	return 0;
}

int main() 
{	
	DICT* dict = NULL;
	// 结果体初始化数据
	dict_init(&dict);
	char cmd[256];
	char content[256];
	int res = 0;
	while (1)
	{
		// 获取用户输入
		printf("请输入需要翻译的单词:");
		fgets(cmd, sizeof(cmd), stdin);
		// 去掉输入的最后一个字符\n
		cmd[strlen(cmd) - 1] = 0;
		// 搜索判断
		res = search_dict_key(cmd, dict, LINE_NUM, content);
		if (res == 0)
		{
			printf("not found %s key\n", cmd);
		}
		else
		{
			printf("翻译结果为:%s\n", content);
		}

	}


	return 0;
}

在这里插入图片描述

自动获取文本文件的行号

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define LINE_NUM 111102 // 一共222204行,包括原文和译文,每次读两行,所以只要111102行
#define FILENAME "dict.txt"


typedef struct _dict
{
	char* key;
	char* content;
}DICT;

FILE* open_file()
{

	FILE* fp = fopen(FILENAME, "r");
	if (NULL == fp)
	{
		perror("open file error");
		return NULL;
	}
	return fp;

}

void filter_buf(char* buf)
{	
	// buf最后一个字符下标
	int n = strlen(buf) - 1;
	// 从buf最后一个字符开始往前判断是否存在空格、\n、\r、\t,如果存在则下标-1,如#abc\r\t 跳出循环时,下标为c字符的下标
	while (buf[n] == " " || buf[n] == '\n' || buf[n] == "\r" || buf[n] == "\t")
	{
		n--;
	}
	// n+1表示有效字符后面的无效字符置为0即可,如#abc\r\t\n -> abc0
	buf[n + 1] = 0;


}

void dict_init(DICT** tmp, int n)
{
	
	DICT* p;
	// 结构体指针申请LINE_NUM个DICT结果体大小的空间
	p = malloc(sizeof(DICT) * n);
	int i = 0;
	char* q = NULL;
	char buf[256];
	FILE* fp = open_file(); // 打开dict.txt文件
	while (1)
	{
		q = fgets(buf, sizeof(buf), fp);  // 读取一行数据 即原文
		if (NULL == q)
		{
			break;
		}

		filter_buf(buf); // 过滤掉单词后面的隐藏的字符如\r \t \n等
		p[i].key = malloc(strlen(buf) + 1);  // 给存储单词p[i].key开辟空间
		strcpy(p[i].key, buf + 1); // buf+1 取#后面的原文
		q = fgets(buf, sizeof(buf), fp);  // 读取一行数据 即译文
		p[i].content = malloc(strlen(buf) + 1);
		strcpy(p[i].content, buf + 6);  // buf+6取Trans:后面的译文
		i++;
	}
	fclose(fp);
	// 修改实参dict的值
	*tmp = p;
	return;
}

int search_dict_key(char* cmd, DICT* dict, int n, char* content)
{
	for (int i = 0; i < n; i++)
	{	
		// 比较终端输入的字符串与结构体中的key是否相同, 相同则将key对应的content字符串内容拷贝到形参content所指的地址
		if (strcmp(cmd, dict[i].key) == 0) 
		{
			strcpy(content, dict[i].content);
			return 1;
		
		}
	}
	// 没有找到返回
	return 0;
}

int get_file_lineNum()
{	
	char* q = NULL;
	char buf[256];
	FILE* fp = open_file();
	int i = 0;
	while (1)
	{
		q = fgets(buf, sizeof(buf), fp);  // 读取一行数据 即原文
		if (NULL == q)
		{
			break;
		}
		q = fgets(buf, sizeof(buf), fp);  // 读取一行数据 即译文
		i++;
	}
	fclose(fp);
	return i;
}

int main() 
{	
	DICT* dict = NULL;
	int n = 0;
	n = get_file_lineNum();
	printf("n=%d\n", n);
	// 结果体初始化数据
	dict_init(&dict, n);
	char cmd[256];
	char content[256];
	int res = 0;
	while (1)
	{
		// 获取用户输入
		printf("请输入需要翻译的单词:");
		fgets(cmd, sizeof(cmd), stdin);
		// 去掉输入的最后一个字符\n
		cmd[strlen(cmd) - 1] = 0;
		// 搜索判断
		res = search_dict_key(cmd, dict, n, content);
		if (res == 0)
		{
			printf("not found %s key\n", cmd);
		}
		else
		{
			printf("翻译结果为:%s\n", content);
		}

	}


	return 0;
}

在这里插入图片描述

添加查询耗时

int main() 
{	
	DICT* dict = NULL;
	int n = 0;
	n = get_file_lineNum();
	printf("n=%d\n", n);
	// 结果体初始化数据
	dict_init(&dict, n);
	char cmd[256];
	char content[256];
	int res = 0;
	LARGE_INTEGER start;
	LARGE_INTEGER end;
	LARGE_INTEGER frequency;
	QueryPerformanceFrequency(&frequency);
	double time;
	while (1)
	{
		// 获取用户输入
		printf("请输入需要翻译的单词:");
		fgets(cmd, sizeof(cmd), stdin);
		// 去掉输入的最后一个字符\n
		cmd[strlen(cmd) - 1] = 0;
		QueryPerformanceCounter(&start); //开始计时  
		// 搜索判断
		res = search_dict_key(cmd, dict, n, content);
		if (res == 0)
		{
			printf("not found %s key\n", cmd);
		}
		else
		{
			printf("翻译结果为:%s\n", content);
		}
		QueryPerformanceCounter(&end); //结束计时  
		time = (double)(end.QuadPart - start.QuadPart) / (double)frequency.QuadPart;
		printf("耗时:%f秒\n ", time);
	}


	return 0;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/64632.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【网络层】BGP协议详解、三种路由协议总结

注&#xff1a;最后有面试挑战&#xff0c;看看自己掌握了吗 文章目录BGP协议------外部网关协议----BGP发言人交换网络可达性信息树形结构---防止兜圈子---交换完整路径信息---路径向量BGP格式---应用层协议-------TCP传送-----先建立TCP连接-----建立BGP session---利用会话交…

[附源码]JAVA毕业设计律师事务管理系统(系统+LW)

[附源码]JAVA毕业设计律师事务管理系统&#xff08;系统LW&#xff09; 项目运行 环境项配置&#xff1a; Jdk1.8 Tomcat8.5 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术…

MyBatisPlus_快速入门_笔记

MyBatisPlus_快速入门_笔记 文章目录MyBatisPlus_快速入门_笔记学习目标一、MyBatisPlus简介1. 入门案例问题导入1.1 SpringBoot整合MyBatisPlus入门程序①&#xff1a;创建新模块&#xff0c;选择Spring初始化&#xff0c;并配置模块相关基础信息③&#xff1a;手动添加MyBati…

规避跑道安全事故,如何进行飞机跑道入侵检测

机场跑道入侵因为危险源综合而复杂&#xff0c;涉及方面很多&#xff0c;管制员、飞行员、环境等众多因素的影响导致&#xff0c;一直难以彻底消除&#xff0c;是全球民航面临的重要核心问题。本文围绕北斗RTK技术&#xff0c;探讨如何防止车辆入侵跑道。 机场跑道面积辽阔&am…

# Navicat报错:1045-Access denied for user root@localhost(using password:YES)怎么解决

文章目录1.删除mysql服务2.新建my.ini配置文件3.重新生成data文件4.重新安装mysql服务&#xff0c;同时绑定my.ini配置文件5.重新设置密码6.修改root用户密码1.删除mysql服务 以管理员身份运行cmd&#xff0c;进入安装目录下的mysql的bin文件下&#xff0c;运行命令&#xff1…

Executor框架

文章目录前言Executor框架简介ScheduledThreadPoolExecutor和ThreadPoolExecutor对比总结前言 在一些场景&#xff0c;我们常常会用到多线程&#xff0c;但是线程的管理又比较麻烦。所以我们通常使用线程池来进行线程的管理&#xff0c;而今天我们将介绍一个java中常常 用来创…

如何通过编码器信号计算输送线/输送带线速度(飞剪、追剪算法基础)

不同品牌PLC如何采集编码器的频率(速度)信号,专栏有系列文章和详细讲解,这里不再赘述,链接地址如下: PLC通过编码器反馈值计算速度的推荐做法(算法解析+ST代码)_RXXW_Dor的博客-CSDN博客_plc运算速度PLC如何测量采集编码器的位置数据,不清楚的可以参看我的另一篇博文:…

【docker】配置深度学习环境

目录基本环境搭建问题与解决容器启动后添加端口映射安装完虚拟环境后 CUDA调用不了opencv的使用问题自定义软件包的使用基本环境搭建 容器基本操作&#xff1a; # 按照服务器配置拉取对应的镜像 docker pull pytorch/pytorch:1.9.0-cuda10.2-cudnn7-devel# 查看主机端口 没有信…

网站部署SSL证书是否会影响网站流量?

给网站部署SSL证书的重要性想必很多站长用户都已知悉&#xff0c;SSL证书是数字证书的一种&#xff0c;由受信任的数字证书颁发机构CA&#xff0c;在验证服务器身份后颁发&#xff0c;具有服务器身份验证和数据传输加密功能。由于SSL证书是部署在服务器上&#xff0c;那么SSL证…

【第二阶段:java基础】第11章:Exception异常(P442-P459)

本系列博客是韩顺平老师java基础课的课程笔记&#xff0c;B站&#xff1a;课程链接&#xff0c;吐血推荐的一套全网最细java教程&#xff0c;获益匪浅&#xff01; 韩顺平P442-P4591. 异常的概念2. 常见的异常运行时异常编译异常3. 异常处理1️⃣try-catch-finally2️⃣throws4…

Java项目:SSM在线化妆品网站

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目为前后台项目&#xff0c;前台为普通用户登录&#xff0c;后台为管理员登录&#xff1b; 管理员角色包含以下功能&#xff1a; 管理员登…

Java入门笔记

目录Java入门笔记快捷键基础准备环境准备Java编译运行流程TODO自定义模板基础语法变量原理标识符标识符命名规则数据类型整数型浮点型类型转换引用数据类型面向对象类和对象判断一个对象是不是某个类方法传参可变参数基本数据类型传参字符串数据类型传参引用数据类型传参静态属…

MySQL索引事务——小记

文章目录索引概念page索引类型B树vsB树主键索引非聚簇索引覆盖索引复合索引/联合索引优化基于B树的索引hash索引事务事务的特性ACID问题隔离级别索引 概念 使用一定的数据结构&#xff0c;来保存索引字段&#xff08;一列或多列&#xff09;对应的数据。以后根据索引字段来检…

低代码常见场景【上】|如何解决业务问题

全文 2105 字 阅读时间约 7 分钟 首发于码匠技术博客 目录 低代码用例 用于解决业务问题的低代码用例 内部系统开发所面临的困境 低代码如何解决上述困境 关于码匠 低代码平台通过在开发和部署应用程序时最大限度地减少编程来减轻 IT 团队的压力&#xff0c;不仅可以帮助…

[附源码]Python计算机毕业设计Django农村人居环境治理监管系统

项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等等。 环境需要 1.运行环境&#xff1a;最好是python3.7.7&#xff0c;…

Java+MySQL 基于Springboot的垃圾分类网站-计算机毕业设计

项目介绍 当前全球都在提倡环境保护&#xff0c;现在社会高速发展&#xff0c;我们每个人每天都会产生很多的垃圾&#xff0c;尤其是工业发展到一定阶段之后这些垃圾的种类也越来越多&#xff0c;如果随意丢弃很可能会造成环境污染&#xff0c;尤其是一些电池等重污染垃圾&…

前端模块化开发

1.模块化产生的背景 Javascript模块化编程&#xff0c;已经成为一个迫切的需求。理想情况下&#xff0c;开发者只需要实现核心的业务逻辑&#xff0c;其他都可以加载别人已经写好的模块。 但是&#xff0c;Javascript不是一种模块化编程语言&#xff0c;它不支持"类&quo…

持续的敏捷转型--我们的经验

作者&#xff1a;Shalini Joshi、 Syed Tamkeen Banu 在这篇文章中&#xff0c;我们将分享自己的经验和教训&#xff0c;说明组织可能在哪些方面会失败&#xff0c;以及可以采取哪些积极措施。 一、简介 如今&#xff0c;大多数组织为了获取更快的交付、更高的商业价值和更好的…

Markdown使用模板

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注…

智能仓储机器人设计

目录 第一章 绪论 1 1.1 研究的背景与意义[1] 1 1.2 机器人的研究现状[4] 2 1.3机器人的发展趋势 4 1.4本文的主要研究内容 5 第二章 机器人总体方案设计 7 2.1 小型仓储机器人的功能 7 2.2 传感器系统[13] 7 2.3 移动载体 7 2.4 自由度与机器人的运作 8 2.5 控制方式的选择 9 …