最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C/C++實(shí)現(xiàn)目錄監(jiān)視器的方法詳解

 更新時(shí)間:2024年04月16日 09:33:03   作者:余識-  
這篇文章主要介紹了C/C++ 實(shí)現(xiàn)目錄監(jiān)視器的方法,然后網(wǎng)上查到的基本就有三種方法,使用FindFirstChangeNotification等系列函數(shù),使用ReadDirectoryChangesW函數(shù)和使用change journals,本文使用了第二種方式來實(shí)現(xiàn)一個(gè)目錄監(jiān)視,需要的朋友可以參考下

前言

突然想寫個(gè)目錄監(jiān)視器玩玩,然后網(wǎng)上查到的基本就有三種方法:

  1. 使用FindFirstChangeNotification等系列函數(shù),缺點(diǎn)很明顯,只能檢測目錄下的文件是否發(fā)生變化,卻不知道是哪個(gè)文件發(fā)生了變化,過于簡陋,就不予考慮了
  2. 使用ReadDirectoryChangesW函數(shù),該函數(shù)就要比上面那種詳細(xì)一點(diǎn),會返回具體發(fā)生變化的文件名稱,但如果檢測目錄發(fā)生大量變化,很可能會遺漏某些文件變化事件,且必須軟件持續(xù)運(yùn)行才行
  3. 使用change journals,該方式當(dāng)然是最好的,甚至可以無需軟件持續(xù)運(yùn)行,但同樣它也是最為復(fù)雜的,大名鼎鼎的everything似乎就是用的這種方法

綜合考慮之下,選擇第二種方式來實(shí)現(xiàn)一個(gè)目錄監(jiān)視器,信息較為全面,且使用也較為簡單

一、函數(shù)介紹

可直接點(diǎn)擊官方文檔查看

BOOL ReadDirectoryChangesW(
HANDLE                          hDirectory, //要進(jìn)行監(jiān)視的目錄句柄,使用createfile函數(shù)得到
LPVOID                          lpBuffer, //存放發(fā)生了改變的文件信息
DWORD                           nBufferLength, //緩存區(qū)的大小
BOOL                            bWatchSubtree, //是否監(jiān)視子目錄
DWORD                           dwNotifyFilter, //過濾要進(jìn)行監(jiān)視的事件
LPDWORD                         lpBytesReturned, //返回接收到的字節(jié)數(shù)
LPOVERLAPPED                    lpOverlapped, //重疊結(jié)構(gòu),用于異步操作
LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine //例程函數(shù),一般不使用,填NULL
);

該函數(shù)的作用就是監(jiān)視某一個(gè)目錄,當(dāng)以同步方式調(diào)用時(shí)(即lpOverlapped為NULL),該函數(shù)會阻塞,直到文件夾內(nèi)發(fā)生了任何變化,將結(jié)果返回值緩存區(qū)lpBuffer中,用FILE_NOTIFY_INFORMATION結(jié)構(gòu)取得相應(yīng)信息

FILE_NOTIFY_INFORMATION

typedef struct _FILE_NOTIFY_INFORMATION {
  DWORD NextEntryOffset; //取得下一個(gè)信息需要便宜的字節(jié)數(shù),最后一個(gè)時(shí),該值為0
  DWORD Action; //發(fā)生的行為
  DWORD FileNameLength; //發(fā)生改變的文件名長度,按字節(jié)計(jì)數(shù)
  WCHAR FileName[1]; //文件名
} FILE_NOTIFY_INFORMATION, *PFILE_NOTIFY_INFORMATION;

二、基本使用方法

打開要進(jìn)行監(jiān)視的文件夾

HANDLE m_hFile = CreateFileW(L“D:\\ps”, FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);

注意,第二個(gè)參數(shù)必須有FILE_LIST_DIRECTORY,以及倒數(shù)第二個(gè)參數(shù)必須有FILE_FLAG_BACKUP_SEMANTICS,否則失敗

開始監(jiān)視

DWORD lbyte; //得到返回的字節(jié)數(shù)
char buf[4096];
BOOL ret = ReadDirectoryChangesW(m_hFile, m_buf, 4096, true, FILE_NOTIFY_CHANGE_FILE_NAME, &lbyte, NULL, NULL); //阻塞監(jiān)視

當(dāng)函數(shù)返回時(shí),取得結(jié)果

FILE_NOTIFY_INFORMATION* f = (FILE_NOTIFY_INFORMATION*)m_buf; //得到FILE_NOTIFY_INFORMATION結(jié)構(gòu)體,進(jìn)行解析
	//進(jìn)入循環(huán),解析所有信息
do {
	wchar_t* fileName = new wchar_t[f->FileNameLength] {};
	memcpy(fileName, f->FileName, f->FileNameLength);
	//fileInfo.push_back({ fileName,f->Action }); //這里fileName即為得到的文件名稱,f->Action則為該文件發(fā)生的行為
	delete[] fileName;
	f = (FILE_NOTIFY_INFORMATION*)((char*)f + f->NextEntryOffset);
} while (f->NextEntryOffset);

三、封裝為類

class WatchFolder {
	HANDLE m_hFile; //進(jìn)行監(jiān)視的文件句柄
	char* m_buf; //保存文件信息更改的緩存區(qū)
public:
	struct FILE_INFO
	{
		std::wstring name;
		DWORD action;
		FILE_INFO(const wchar_t* fileName, DWORD act) {
			name = fileName;
			action = act;
		}
	};
	//可監(jiān)視的屬性
	enum {
		NOTIFY_FILE_NAME = FILE_NOTIFY_CHANGE_FILE_NAME, //監(jiān)視文件名更改
		NOTIFY_DIR_NAME = FILE_NOTIFY_CHANGE_DIR_NAME, //監(jiān)視目錄名更改
		NOTIFY_ATTRIBUTES = FILE_NOTIFY_CHANGE_ATTRIBUTES, //監(jiān)視文件屬性更改
		NOTIFY_SIZE = FILE_NOTIFY_CHANGE_SIZE, //監(jiān)視文件大小更改
		NOTIFY_LAST_WRITE = FILE_NOTIFY_CHANGE_LAST_WRITE, //監(jiān)視文件最后寫入時(shí)間更改
		NOTIFY_LAST_ACCESS = FILE_NOTIFY_CHANGE_LAST_ACCESS, //監(jiān)視文件最后訪問時(shí)間更改
		NOTIFY_CREATION = FILE_NOTIFY_CHANGE_CREATION, //監(jiān)視文件創(chuàng)建
		NOTIFY_SECURITY = FILE_NOTIFY_CHANGE_SECURITY, //監(jiān)視文件安全描述符更改
		NOTIFY_ALL = NOTIFY_DIR_NAME|NOTIFY_FILE_NAME|NOTIFY_SIZE| NOTIFY_LAST_WRITE| NOTIFY_LAST_ACCESS| NOTIFY_CREATION| NOTIFY_ATTRIBUTES| NOTIFY_SECURITY //監(jiān)視所有情況
	};
	//發(fā)生的行為
	enum {
		ACTION_ADD = FILE_ACTION_ADDED, //文件添加
		ACTION_REMOVE = FILE_ACTION_REMOVED, //文件刪除
		ACTION_MODIFIED = FILE_ACTION_MODIFIED, //文件更改
		ACTION_RENAME_OLD=FILE_ACTION_RENAMED_OLD_NAME, //文件重命名(舊名字)
		ACTION_RENAME_NEW=FILE_ACTION_RENAMED_NEW_NAME //文件重命名(新名字)
	};
public:
	WatchFolder(int bufSize=4096) {
		m_hFile = nullptr;
		m_buf = new char[bufSize];
	}
	~WatchFolder()
	{
		Close();
		delete[] m_buf;
	}
	/**
	 * @brief 初始化要進(jìn)行監(jiān)視的文件
	 * @param dir 
	 * @return 
	*/
	bool Init(const std::wstring& dir) {
		if (m_hFile != nullptr) {
			CloseHandle(m_hFile);
			m_hFile = nullptr;
		}
		//打開文件
		m_hFile = CreateFileW(dir.data(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
		return m_hFile != nullptr;
	}
	/**
	 * @brief 關(guān)閉打開的文件句柄
	*/
	void Close() {
		if(m_hFile!=NULL)	CloseHandle(m_hFile);
	}
	/**
	 * @brief 開始監(jiān)視文件夾
	 * @param fileInfo 返回發(fā)生改變的文件信息
	 * @param filter 要進(jìn)行監(jiān)視的文件行為,可使用WatchFolder::NOTIFY_*
	 * @param IsWatchSubTree 是否監(jiān)視子目錄
	 * @return 存在文件更改信息返回true,否則返回false
	*/
	bool BeginMonitor(std::list<FILE_INFO>& fileInfo, DWORD filter, bool IsWatchSubTree = false) {
		fileInfo.clear(); //清空列表
		DWORD lbyte; //得到返回的字節(jié)數(shù)
		BOOL ret = ReadDirectoryChangesW(m_hFile, m_buf, 4096, IsWatchSubTree, filter, &lbyte, NULL, NULL); //阻塞監(jiān)視
		if (!ret ) return false; //失敗
		FILE_NOTIFY_INFORMATION* f = (FILE_NOTIFY_INFORMATION*)m_buf; //得到FILE_NOTIFY_INFORMATION結(jié)構(gòu)體,進(jìn)行解析
		//進(jìn)入循環(huán),解析所有信息
		do {
			wchar_t* fileName = new wchar_t[f->FileNameLength] {};
			memcpy(fileName, f->FileName, f->FileNameLength);
			fileInfo.push_back({ fileName,f->Action });
			delete[] fileName;
			f = (FILE_NOTIFY_INFORMATION*)((char*)f + f->NextEntryOffset);
		} while (f->NextEntryOffset);
		memset(m_buf, 0, lbyte); //清空緩存區(qū)
		return !fileInfo.empty();
	}
};

該類注釋很詳細(xì),便不過多解說

需要注意的是,類中定義了兩個(gè)枚舉與一個(gè)結(jié)構(gòu)體,結(jié)構(gòu)體用于保存文件信息,而兩個(gè)枚舉類型,只是將官方文檔中列出的自己重新定義了一遍,方便后面使用

該類的使用方法:

	WatchFolder fol;
	bool ret = fol.Init(L"D:\\");
	if (!ret) {
		cout << "初始化失敗";
		return -1;
	}
	list<WatchFolder::FILE_INFO> res;
	while (fol.BeginMonitor(res, WatchFolder::NOTIFY_ALL, true)) {
		for (auto& i : res) {
			switch (i.action)
			{
			case WatchFolder::ACTION_ADD:
				wcout << i.name << L":\t文件被添加" << endl;
				break;
			case WatchFolder::ACTION_REMOVE:
				wcout << i.name << L":\t文件被刪除" << endl;
				break;
			case WatchFolder::ACTION_MODIFIED:
				wcout << i.name << L":\t文件被更改" << endl;
				break;
			case WatchFolder::ACTION_RENAME_OLD:
				wcout << i.name << L":\t文件重命名" << endl;
				break;
			case WatchFolder::ACTION_RENAME_NEW:
				wcout << i.name << L":\t文件新名字" << endl;
				break;
			default:
				break;
			}
		}
	}

四、控制臺版目錄監(jiān)視器

完整代碼:

#include<iostream>
#include<string>
#include<Windows.h>
#include<list>
#include<locale>
using namespace std;

class WatchFolder {
	HANDLE m_hFile; //進(jìn)行監(jiān)視的文件句柄
	char* m_buf; //保存文件信息更改的緩存區(qū)
public:
	struct FILE_INFO
	{
		std::wstring name;
		DWORD action;
		FILE_INFO(const wchar_t* fileName, DWORD act) {
			name = fileName;
			action = act;
		}
	};
	//可監(jiān)視的屬性
	enum {
		NOTIFY_FILE_NAME = FILE_NOTIFY_CHANGE_FILE_NAME, //監(jiān)視文件名更改
		NOTIFY_DIR_NAME = FILE_NOTIFY_CHANGE_DIR_NAME, //監(jiān)視目錄名更改
		NOTIFY_ATTRIBUTES = FILE_NOTIFY_CHANGE_ATTRIBUTES, //監(jiān)視文件屬性更改
		NOTIFY_SIZE = FILE_NOTIFY_CHANGE_SIZE, //監(jiān)視文件大小更改
		NOTIFY_LAST_WRITE = FILE_NOTIFY_CHANGE_LAST_WRITE, //監(jiān)視文件最后寫入時(shí)間更改
		NOTIFY_LAST_ACCESS = FILE_NOTIFY_CHANGE_LAST_ACCESS, //監(jiān)視文件最后訪問時(shí)間更改
		NOTIFY_CREATION = FILE_NOTIFY_CHANGE_CREATION, //監(jiān)視文件創(chuàng)建
		NOTIFY_SECURITY = FILE_NOTIFY_CHANGE_SECURITY, //監(jiān)視文件安全描述符更改
		NOTIFY_ALL = NOTIFY_DIR_NAME|NOTIFY_FILE_NAME|NOTIFY_SIZE| NOTIFY_LAST_WRITE| NOTIFY_LAST_ACCESS| NOTIFY_CREATION| NOTIFY_ATTRIBUTES| NOTIFY_SECURITY //監(jiān)視所有情況
	};
	//發(fā)生的行為
	enum {
		ACTION_ADD = FILE_ACTION_ADDED, //文件添加
		ACTION_REMOVE = FILE_ACTION_REMOVED, //文件刪除
		ACTION_MODIFIED = FILE_ACTION_MODIFIED, //文件更改
		ACTION_RENAME_OLD=FILE_ACTION_RENAMED_OLD_NAME, //文件重命名(舊名字)
		ACTION_RENAME_NEW=FILE_ACTION_RENAMED_NEW_NAME //文件重命名(新名字)
	};
public:
	WatchFolder(int bufSize=4096) {
		m_hFile = nullptr;
		m_buf = new char[bufSize];
	}
	~WatchFolder()
	{
		Close();
		delete[] m_buf;
	}
	/**
	 * @brief 初始化要進(jìn)行監(jiān)視的文件
	 * @param dir 
	 * @return 
	*/
	bool Init(const std::wstring& dir) {
		if (m_hFile != nullptr) {
			CloseHandle(m_hFile);
			m_hFile = nullptr;
		}
		//打開文件
		m_hFile = CreateFileW(dir.data(), FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE| FILE_SHARE_DELETE, 0, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, 0);
		return m_hFile != nullptr;
	}
	/**
	 * @brief 關(guān)閉打開的文件句柄
	*/
	void Close() {
		if(m_hFile!=NULL)	CloseHandle(m_hFile);
	}
	/**
	 * @brief 開始監(jiān)視文件夾
	 * @param fileInfo 返回發(fā)生改變的文件信息
	 * @param filter 要進(jìn)行監(jiān)視的文件行為,可使用WatchFolder::NOTIFY_*
	 * @param IsWatchSubTree 是否監(jiān)視子目錄
	 * @return 存在文件更改信息返回true,否則返回false
	*/
	bool BeginMonitor(std::list<FILE_INFO>& fileInfo, DWORD filter, bool IsWatchSubTree = false) {
		fileInfo.clear(); //清空列表
		DWORD lbyte; //得到返回的字節(jié)數(shù)
		BOOL ret = ReadDirectoryChangesW(m_hFile, m_buf, 4096, IsWatchSubTree, filter, &lbyte, NULL, NULL); //阻塞監(jiān)視
		if (!ret ) return false; //失敗
		FILE_NOTIFY_INFORMATION* f = (FILE_NOTIFY_INFORMATION*)m_buf; //得到FILE_NOTIFY_INFORMATION結(jié)構(gòu)體,進(jìn)行解析
		//進(jìn)入循環(huán),解析所有信息
		do {
			wchar_t* fileName = new wchar_t[f->FileNameLength] {};
			memcpy(fileName, f->FileName, f->FileNameLength);
			fileInfo.push_back({ fileName,f->Action });
			delete[] fileName;
			f = (FILE_NOTIFY_INFORMATION*)((char*)f + f->NextEntryOffset);
		} while (f->NextEntryOffset);
		memset(m_buf, 0, lbyte); //清空緩存區(qū)
		return !fileInfo.empty();
	}
};



int main() {
	setlocale(LC_ALL, "");
	WatchFolder fol;
	bool ret = fol.Init(L"D:\\");
	if (!ret) {
		cout << "初始化失敗";
		return -1;
	}
	list<WatchFolder::FILE_INFO> res;
	while (fol.BeginMonitor(res, WatchFolder::NOTIFY_ALL, true)) {
		for (auto& i : res) {
			switch (i.action)
			{
			case WatchFolder::ACTION_ADD:
				wcout << i.name << L":\t文件被添加" << endl;
				break;
			case WatchFolder::ACTION_REMOVE:
				wcout << i.name << L":\t文件被刪除" << endl;
				break;
			case WatchFolder::ACTION_MODIFIED:
				wcout << i.name << L":\t文件被更改" << endl;
				break;
			case WatchFolder::ACTION_RENAME_OLD:
				wcout << i.name << L":\t文件重命名" << endl;
				break;
			case WatchFolder::ACTION_RENAME_NEW:
				wcout << i.name << L":\t文件新名字" << endl;
				break;
			default:
				break;
			}
		}
	}
}

至此,一個(gè)簡單的控制臺文件目錄監(jiān)視器就完成了

五、添加界面

簡便起見,就直接使用MFC了

成品大概這樣:

在這里插入圖片描述

感覺有點(diǎn)難看,還是應(yīng)該用Qt的,算了,都做完了,也難得改了

該文件邏輯與控制臺大致相似,但由于MFC特殊性,所以會有一些奇怪操作

上面寫的類,我直接放在了自動MFC自動生成的這個(gè)文件里面

在這里插入圖片描述

對話框WatchFolderDlg.h文件中,關(guān)鍵成員函數(shù)為

	bool m_IsWatch; //標(biāo)志當(dāng)前是否正在監(jiān)視
	DWORD m_filter; //要進(jìn)行監(jiān)視的項(xiàng)
	WatchFolder wf; //封裝的監(jiān)視類

開始監(jiān)視按鈕函數(shù):

void CWatchFolderDlg::OnBnClickedBtnBegin()
{
	UpdateData(); //將控件中的數(shù)據(jù)更新到變量中
	if (m_IsWatch) { //如果正在監(jiān)視,則停止監(jiān)視
		m_IsWatch = false; 
		TerminateThread(hThread, 0); 
		wf.Close();
		SetDlgItemTextW(IDC_BTN_BEGIN, L"開始監(jiān)視");
		return;
	}

	m_IsWatch = true;

	bool ret = wf.Init(m_dirPath.GetBuffer());

	if (!ret) {
		AfxMessageBox(L"監(jiān)視失?。?);
		m_IsWatch = false;
		return;
	}

	DWORD tFilter = 0;
	tFilter != WatchFolder::NOTIFY_FILE_NAME; //默認(rèn)值

	if (m_radName.GetCheck() == BST_CHECKED) {
		tFilter |= WatchFolder::NOTIFY_FILE_NAME;
		tFilter |= WatchFolder::NOTIFY_DIR_NAME;
	}
	if (m_radAttri.GetCheck() == BST_CHECKED) {
		tFilter |= WatchFolder::NOTIFY_ATTRIBUTES;
	}

	if (m_radSize.GetCheck() == BST_CHECKED) {
		tFilter |= WatchFolder::NOTIFY_SIZE;
	}

	if (m_radTime.GetCheck() == BST_CHECKED) {
		tFilter |= WatchFolder::NOTIFY_LAST_ACCESS;
		tFilter |= WatchFolder::NOTIFY_LAST_WRITE;
	}
	if (m_radSecurity.GetCheck() == BST_CHECKED) {
		tFilter |= WatchFolder::NOTIFY_SECURITY;
	}
	m_filter = tFilter;  //得到用戶選擇的要進(jìn)行監(jiān)視的屬性

	DWORD TID;
	hThread = CreateThread(0, 0, watchThread, this, 0, &TID); //創(chuàng)建線程,將該類指針作為參數(shù)傳入,方便訪問控件與成員變量


	SetDlgItemTextW(IDC_BTN_BEGIN, L"停止監(jiān)視");

}

比較特殊的就是將this指針傳入進(jìn)線程了,這是為了讓新開的線程能訪問控件,更新數(shù)據(jù)等

DWORD WINAPI watchThread(LPVOID lparam) {
	CWatchFolderDlg* dlg = (CWatchFolderDlg*)lparam;
	std::list<WatchFolder::FILE_INFO> res;
	while (dlg->m_IsWatch && dlg->wf.BeginMonitor(res, dlg->m_filter, true)) {
		CString log;
		for (auto& i : res) {
			switch (i.action)
			{
			case WatchFolder::ACTION_ADD:
				log.Format(_T("%s:\t文件添加\r\n"), i.name.data());
				break;
			case WatchFolder::ACTION_REMOVE:
				log.Format(_T("%s:\t文件移除\r\n"), i.name.data());
				break;
			case WatchFolder::ACTION_MODIFIED:
				log.Format(_T("%s:\t文件更改\r\n"), i.name.data());
				break;
			case WatchFolder::ACTION_RENAME_OLD:
				log.Format(_T("%s:\t文件重命名\r\n"), i.name.data());
				break;
			case WatchFolder::ACTION_RENAME_NEW:
				log.Format(_T("%s:\t文件新名稱\r\n"), i.name.data());
				break;
			default:
				break;
			}
		}
		CString old;
		dlg->m_etLog.GetWindowTextW(old);
		dlg->m_etLog.SetWindowTextW(old + log);
	}
	dlg->wf.Close();
	return 0;
}

以上就是C/C++實(shí)現(xiàn)目錄監(jiān)視器的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于C/C++目錄監(jiān)視器的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vs2022?x64?C/C++和匯編混編(案例代碼)

    vs2022?x64?C/C++和匯編混編(案例代碼)

    這篇文章主要介紹了vs2022?x64?C/C++和匯編混編,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • 如何使用C語言將數(shù)字、字符等數(shù)據(jù)寫入、輸出到文本文件中

    如何使用C語言將數(shù)字、字符等數(shù)據(jù)寫入、輸出到文本文件中

    在分析數(shù)據(jù)時(shí),首先要解決數(shù)據(jù)的保存問題,下面這篇文章主要給大家介紹了關(guān)于如何使用C語言將數(shù)字、字符等數(shù)據(jù)寫入、輸出到文本文件中的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-06-06
  • json格式解析和libjson的用法介紹(關(guān)于cjson的使用方法)

    json格式解析和libjson的用法介紹(關(guān)于cjson的使用方法)

    下面小編就為大家?guī)硪黄猨son格式解析和libjson的用法介紹(關(guān)于cjson的使用方法)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-12-12
  • QT中QDataStream二進(jìn)制數(shù)據(jù)讀寫的實(shí)現(xiàn)

    QT中QDataStream二進(jìn)制數(shù)據(jù)讀寫的實(shí)現(xiàn)

    本文主要介紹了QT中QDataStream二進(jìn)制數(shù)據(jù)讀寫的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • c語言實(shí)現(xiàn)的貨物管理系統(tǒng)實(shí)例代碼(增加刪除 查找貨物信息等功能)

    c語言實(shí)現(xiàn)的貨物管理系統(tǒng)實(shí)例代碼(增加刪除 查找貨物信息等功能)

    這篇文章主要介紹了c語言實(shí)現(xiàn)的貨物管理系統(tǒng),可增加刪除、查找貨物信息、顯示貨物信息、排序貨物銷量等操作,大家參考使用吧
    2013-11-11
  • C++簡明講解類型轉(zhuǎn)換的使用與作用

    C++簡明講解類型轉(zhuǎn)換的使用與作用

    類型轉(zhuǎn)換(type?cast),是高級語言的一個(gè)基本語法。它被實(shí)現(xiàn)為一個(gè)特殊的運(yùn)算符,以小括號內(nèi)加上類型名來表示,接下來讓我們一起來詳細(xì)了解
    2022-04-04
  • C語言 TerminateProcess函數(shù)案例詳解

    C語言 TerminateProcess函數(shù)案例詳解

    這篇文章主要介紹了C語言 TerminateProcess函數(shù)案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • C++使用chrono庫處理日期和時(shí)間的實(shí)現(xiàn)方法

    C++使用chrono庫處理日期和時(shí)間的實(shí)現(xiàn)方法

    C++11 中提供了日期和時(shí)間相關(guān)的庫 chrono,通過 chrono 庫可以很方便地處理日期和時(shí)間,本文主要介紹了C++使用chrono庫處理日期和時(shí)間的實(shí)現(xiàn)方法,感興趣的小伙伴們可以參考一下
    2021-09-09
  • C++特性:迭代器

    C++特性:迭代器

    這篇文章主要介紹了C++特性:迭代器,本文主要通過介紹迭代器,迭代器和指針的區(qū)別,容器迭代器的使用等方面,需要的朋友可以參考下
    2021-06-06
  • Qt中JSON操作的具體使用

    Qt中JSON操作的具體使用

    本文主要介紹了Qt中JSON操作的具體使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08

最新評論

台东市| 昭通市| 营口市| 上杭县| 北海市| 石台县| 墨江| 连云港市| 垦利县| 荆门市| 惠来县| 通渭县| 金坛市| 鄂州市| 安阳市| 托克逊县| 凤山市| 舒兰市| 鄂托克前旗| 那坡县| 郁南县| 湘乡市| 东乌珠穆沁旗| 霍林郭勒市| 林口县| 阳曲县| 广元市| 新乡县| 哈密市| 华亭县| 昭平县| 宝兴县| 丹东市| 济源市| 治多县| 安西县| 安庆市| 马关县| 淮南市| 蓬安县| 延安市|