亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

C++雙線程調(diào)用網(wǎng)絡(luò)攝像頭與多線程調(diào)用多攝像頭同步執(zhí)行方法詳細講解

 更新時間:2022年11月16日 16:23:44   作者:zk_ken  
這篇文章主要介紹了C++雙線程調(diào)用網(wǎng)絡(luò)攝像頭與多線程調(diào)用多攝像頭同步執(zhí)行方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧

在調(diào)用網(wǎng)絡(luò)攝像頭處理自己的算法時,當解碼的速度與算法運行的速度差太多時,會出現(xiàn)類似下面的錯誤

error while decoding MB 148 4, bytestream

所以需要使用兩個線程,一個線程調(diào)用攝像頭,一個線程用來處理圖像。

一、使用雙線程調(diào)用網(wǎng)絡(luò)攝像頭并執(zhí)行算法

方法一

#include <iostream>
#include <thread>
#include <mutex>
#include <atomic>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
static std::mutex mutex;
static std::atomic_bool isOpen;
static void cameraThreadFunc(std::string camId, cv::Mat* pFrame)
{
    cv::VideoCapture capture(camId);
    //capture.set(cv::CAP_PROP_FOURCC, CV_FOURCC('M', 'J', 'P', 'G'));
    capture.set(cv::CAP_PROP_FPS, 30);
    if (!capture.isOpened()) {
        isOpen = false;
        std::cout << "Failed to open camera with index " << camId << std::endl;
    }
    cv::Mat frame;
    while (isOpen) {
        capture >> frame;
        if (mutex.try_lock()) {
            frame.copyTo(*pFrame);
            mutex.unlock();
        }
        cv::waitKey(5);
    }
    capture.release();
}
int main(int argc, char* argv[])
{
    std::string rtsps = "rtsp://admin:bs123456@192.168.1.64:554/h264/ch1/main/av_stream/1";
    isOpen = true;
    cv::Mat frame(1440, 2560, CV_8UC3);
    //cv::Mat* frame = new cv::Mat(1440, 2560, CV_8UC3);
    std::thread thread(cameraThreadFunc, rtsps, &frame); //調(diào)用攝像頭
    //std::thread thread(cameraThreadFunc, rtsps, frame);
    //*****************************************************
    //調(diào)用自己的算法處理圖像
    void* p_algorithm;
    p_algorithm = (void*)(new WindNetDetect());
    std::string net_bins = "./models/visdrone_1009-opt.bin";
    std::string net_paras = "./models/visdrone_1009-opt.param";
    int init_res = ((WindNetDetect*)p_algorithm)->init1(net_bins, net_paras);
    WindNetDetect* tmp = (WindNetDetect*)(p_algorithm);
    std::vector<Object> objects;
    //*****************************************************
    while (isOpen) {
        //*********************************
        //調(diào)用目標檢測的算法
        tmp->detect(frame, objects);
        tmp->draw_objects(frame, objects);
        //*********************************
        if (cv::waitKey(1) == 'q') {
            break;
        }
    }
    frame.release();
    isOpen = false;
    thread.join();
    return 0;
}

方法二

// video_test.cpp
#include <iostream>
#include <string>
#include <thread>
#include <mutex>
#include <atomic>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
class VideoCaptureMT {
public:
	VideoCaptureMT(int index, int height=480, int width=640);
	VideoCaptureMT(std::string filePath, int height=480, int width=640);
	~VideoCaptureMT();
	bool isOpened() {
		return m_IsOpen;
	}
	void release() {
		m_IsOpen = false;
	}
	bool read(cv::Mat& frame);
private:
	void captureInit(int index, std::string filePath, int height, int width);
	void captureFrame();
	cv::VideoCapture* m_pCapture;
	cv::Mat* m_pFrame;
	std::mutex* m_pMutex;
	std::thread* m_pThread;
	std::atomic_bool m_IsOpen;
};
VideoCaptureMT::VideoCaptureMT(int index, int height, int width)
{
	captureInit(index, std::string(), height, width);
}
VideoCaptureMT::VideoCaptureMT(std::string filePath, int height, int width)
{
	captureInit(0, filePath, height, width);
}
VideoCaptureMT::~VideoCaptureMT()
{
	m_IsOpen = false;
	m_pThread->join();
	if (m_pCapture->isOpened()) {
		m_pCapture->release();
	}
	delete m_pThread;
	delete m_pMutex;
	delete m_pCapture;
	delete m_pFrame;
}
void VideoCaptureMT::captureInit(int index, std::string filePath, int height, int width)
{
	if (!filePath.empty()) {
		m_pCapture = new cv::VideoCapture(filePath);
	}
	else {
		m_pCapture = new cv::VideoCapture(index);
	}
	m_pCapture->set(cv::CAP_PROP_FRAME_WIDTH, width);
	m_pCapture->set(cv::CAP_PROP_FRAME_HEIGHT, height);
	m_pCapture->set(cv::CAP_PROP_FPS, 30);
	m_IsOpen = true;
	m_pFrame = new cv::Mat(height, width, CV_8UC3);
	m_pMutex = new std::mutex();
	m_pThread = new std::thread(&VideoCaptureMT::captureFrame, this);
}
void VideoCaptureMT::captureFrame()
{
	cv::Mat frameBuff;
	while (m_IsOpen) {
		(*m_pCapture) >> frameBuff;
		if (m_pMutex->try_lock()) {
			frameBuff.copyTo(*m_pFrame);
			m_pMutex->unlock();
		}
		cv::waitKey(5);
	}
}
bool VideoCaptureMT::read(cv::Mat& frame)
{
	if (m_pFrame->empty()) {
		m_IsOpen = false;
	}
	else {
		m_pMutex->lock();
		m_pFrame->copyTo(frame);
		m_pMutex->unlock();
	}
	return m_IsOpen;
}
int main(int argc, char* argv[])
{
	VideoCaptureMT capture(0);
	cv::Mat frame, gray;
	while (capture.isOpened()) {
		if (!capture.read(frame)) {
			break;
		}
		cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
		cv::blur(gray, gray, cv::Size(3, 3));
		cv::Canny(gray, gray, 5 , 38 , 3);
		cv::waitKey(100);
		cv::imshow("image", gray);
        if (cv::waitKey(5) == 'q') {
			break;
		}
	}
	capture.release();
	return 0;
}

二、使用多線程調(diào)用多路攝像頭并同步執(zhí)行多個算法

使用兩個線程調(diào)用兩個函數(shù),get_cam1中包含了調(diào)用網(wǎng)絡(luò)攝像頭的類VideoCaptureMT (見上面代碼),以及調(diào)用算法。另外一個函數(shù)是一樣的。代碼如下 :

void get_cam1()
{
	clock_t start, end, end1, end2;
	std::string rtsps = "rtsp://admin:bs123456@192.168.1.64:554/h264/ch1/main/av_stream/1";
	VideoCaptureMT capture(rtsps);
	//VideoCaptureMT capture, captureusb;
	cv::namedWindow("外接攝像頭檢測", 0);
	cv::Mat frame, gray;
	while (capture.isOpened()) {
		std::lock_guard<std::mutex> mtx_locker(mtx);
		start = clock();
		if (!capture.read(frame)) {
			break;
		}
		//gray = frame;
		end = clock();
		std::vector<Object> objects;
		tmp->detect(frame, objects);
		for (size_t i = 0; i < objects.size(); i++)
		{
			const Object& obj = objects[i];
			fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,
				obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
			cv::rectangle(frame, obj.rect, cv::Scalar(255, 0, 0));
			char text[256];
			//sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);
			sprintf(text, "%s", class_names[obj.label]);
			int baseLine = 0;
			cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
			int x = obj.rect.x;
			int y = obj.rect.y - label_size.height - baseLine;
			if (y < 0)
				y = 0;
			if (x + label_size.width > frame.cols)
				x = frame.cols - label_size.width;
			cv::rectangle(frame, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
				cv::Scalar(255, 255, 255), -1);
			cv::putText(frame, text, cv::Point(x, y + label_size.height),
				cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
		}
		//cv::imwrite("./result20.jpg", image);
		cv::imshow("外接攝像頭檢測", frame);
		end2 = clock();
		float rumtime = (float)(end2 - start) / CLOCKS_PER_SEC;
		std::stringstream buf;
		buf.precision(3);//??????????
		buf.setf(std::ios::fixed);//????С??λ
		buf << rumtime;
		std::string strtime;
		strtime = buf.str();
		std::cout << "strtime1111 = " << strtime << std::endl;
		//start = end2;
		if (cv::waitKey(5) == 'q') {
			break;
		}
	}
	capture.release();
}
void get_camusb()
{
	clock_t start, end, end1, end2;
	std::string rtsps = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4";
	VideoCaptureMT capture(rtsps);
	cv::Mat frameusb;
	cv::namedWindow("外接攝像頭檢測1", 0);
	//void* p_algorithmusb;
	//p_algorithmusb = (void*)(new WindNetDetect());
	//std::string net_binsusb = "./models/visdrone_1009-opt.bin";
	//std::string net_parasusb = "./models/visdrone_1009-opt.param";
	//int init_res = ((WindNetDetect*)p_algorithmusb)->init1(net_binsusb, net_parasusb);
	//WindNetDetect* tmp = (WindNetDetect*)(p_algorithmusb);
	while (capture.isOpened()) {
		std::lock_guard<std::mutex> mtx_locker(mtx);
		start = clock();
		if (!capture.read(frameusb)) {
			break;
		}
		//gray = frame;
		end = clock();
		std::vector<Object> objectsusb;
		tmp->detect(frameusb, objectsusb);
		for (size_t i = 0; i < objectsusb.size(); i++)
		{
			const Object& obj = objectsusb[i];
			fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,
				obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
			cv::rectangle(frameusb, obj.rect, cv::Scalar(255, 0, 0));
			char text[256];
			//sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);
			sprintf(text, "%s", class_names[obj.label]);
			int baseLine = 0;
			cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
			int x = obj.rect.x;
			int y = obj.rect.y - label_size.height - baseLine;
			if (y < 0)
				y = 0;
			if (x + label_size.width > frameusb.cols)
				x = frameusb.cols - label_size.width;
			cv::rectangle(frameusb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
				cv::Scalar(255, 255, 255), -1);
			cv::putText(frameusb, text, cv::Point(x, y + label_size.height),
				cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
		}
		//cv::imwrite("./result20.jpg", image);
		cv::imshow("外接攝像頭檢測1", frameusb);
		end2 = clock();
		float rumtime = (float)(end2 - start) / CLOCKS_PER_SEC;
		std::stringstream buf;
		buf.precision(3);//??????????
		buf.setf(std::ios::fixed);//????С??λ
		buf << rumtime;
		std::string strtime;
		strtime = buf.str();
		std::cout << "strtime1111 = " << strtime << std::endl;
		//start = end2;
		if (cv::waitKey(5) == 'q') {
			break;
		}
	}
	capture.release();
}
int main() {
	void* p_algorithm;
	p_algorithm = (void*)(new WindNetDetect());
	std::string net_bins = "./models/visdrone_1009-opt.bin";
	std::string net_paras = "./models/visdrone_1009-opt.param";
	int init_res = ((WindNetDetect*)p_algorithm)->init1(net_bins, net_paras);
	tmp = (WindNetDetect*)(p_algorithm);
	//HANDLE hThread1 = CreateThread(NULL, 0, get_cam1, NULL, 0, NULL);
	//CloseHandle(hThread1);
	//HANDLE hThread2 = CreateThread(NULL, 0, get_camusb, NULL, 0, NULL);
	//CloseHandle(hThread2);
	std::thread thrd_1(get_cam1);
	std::thread thrd_2(get_camusb);
	thrd_1.join();
	thrd_2.join();
	while (true)
	{
		std::cout << "Main Thread Display!" << std::endl;
		Sleep(3000);
	}
	return 0;
}

運行上面的代碼時,兩個函數(shù)沒有同步運行。如下strtime1111表示一個線程調(diào)用的函數(shù),strtime2222表示另一個線程調(diào)用的函數(shù),能看出沒有同時調(diào)用兩個函數(shù)。

所以需對代碼進行如下改進:

static std::mutex mutexk;
void get_cam1()
{
	clock_t start, end, end1, end2;
	std::string rtsps = "rtsp://admin:bs123456@192.168.1.64:554/h264/ch1/main/av_stream/1";
	VideoCaptureMT capture(rtsps);
	cv::Mat frame;
	cv::namedWindow("ss", 0);
	while (capture.isOpened()) {
		//pthread_rwlock_rdlock(&rwlock);
		//std::lock_guard<std::mutex> mtx_locker(mtx);
		start = clock();
		if (!capture.read(frame)) {
			break;
		}
		if (mutexk.try_lock()) {
			//gray = frame;
			end = clock();
			std::vector<Object> objects;
			tmp->detect(frame, objects);
			//tmp->draw_objects(frame, objects);
			for (size_t i = 0; i < objects.size(); i++)
			{
				const Object& obj = objects[i];
				fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,
					obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
				cv::rectangle(frame, obj.rect, cv::Scalar(255, 0, 0));
				char text[256];
				//sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);
				sprintf(text, "%s", class_names[obj.label]);
				int baseLine = 0;
				cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
				int x = obj.rect.x;
				int y = obj.rect.y - label_size.height - baseLine;
				if (y < 0)
					y = 0;
				if (x + label_size.width > frame.cols)
					x = frame.cols - label_size.width;
				cv::rectangle(frame, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
					cv::Scalar(255, 255, 255), -1);
				cv::putText(frame, text, cv::Point(x, y + label_size.height),
					cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
			}
			//cv::imwrite("./result20.jpg", image);
			cv::imshow("ss", frame);
			end2 = clock();
			float rumtime = (float)(end2 - start) / CLOCKS_PER_SEC;
			std::stringstream buf;
			buf.precision(3);//??????????
			buf.setf(std::ios::fixed);//????С??λ
			buf << rumtime;
			std::string strtime;
			strtime = buf.str();
			std::cout << "strtime2222 = " << strtime << std::endl;
			//start = end2;
			if (cv::waitKey(5) == 'q') {
				break;
			}
			mutexk.unlock();
		}
	}
	capture.release();
}
void get_camusb()
{
	//std::lock_guard<std::mutex> mtx_locker(mtx);
	clock_t start, end, end1, end2;
	//std::string rtsps = "rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mp4";
	std::string rtsps = "rtsp://admin:bs123456@192.168.1.64:554/h264/ch1/main/av_stream/1";
	VideoCaptureMT capture(rtsps);
	cv::Mat frameusb;
	cv::namedWindow("zz1", 0);
	while (capture.isOpened()) {
		std::lock_guard<std::mutex> mtx_locker1(mtx);
		start = clock();
		if (!capture.read(frameusb)) {
			break;
		}
		if (mutexk.try_lock()) {
			//gray = frame;
			end = clock();
			std::vector<Object> objectsusb;
			tmp->detect(frameusb, objectsusb);
			//tmp->draw_objects(frameusb, objectsusb);
			for (size_t i = 0; i < objectsusb.size(); i++)
			{
				const Object& obj = objectsusb[i];
				fprintf(stderr, "%d = %.5f at %.2f %.2f %.2f x %.2f\n", obj.label, obj.prob,
					obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
				cv::rectangle(frameusb, obj.rect, cv::Scalar(255, 0, 0));
				char text[256];
				//sprintf(text, "%s %.1f%%", class_names[obj.label], obj.prob * 100);
				sprintf(text, "%s", class_names[obj.label]);
				int baseLine = 0;
				cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
				int x = obj.rect.x;
				int y = obj.rect.y - label_size.height - baseLine;
				if (y < 0)
					y = 0;
				if (x + label_size.width > frameusb.cols)
					x = frameusb.cols - label_size.width;
				cv::rectangle(frameusb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
					cv::Scalar(255, 255, 255), -1);
				cv::putText(frameusb, text, cv::Point(x, y + label_size.height),
					cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
			}
			//cv::imwrite("./result20.jpg", image);
			cv::imshow("zz1", frameusb);
			end2 = clock();
			float rumtime = (float)(end2 - start) / CLOCKS_PER_SEC;
			std::stringstream buf;
			buf.precision(3);//??????????
			buf.setf(std::ios::fixed);//????С??λ
			buf << rumtime;
			std::string strtime;
			strtime = buf.str();
			std::cout << "strtime1111 = " << strtime << std::endl;
			//start = end2;
			if (cv::waitKey(5) == 'q') {
				break;
			}
			mutexk.unlock();
		}
	}
	capture.release();
}
int main() {
	void* p_algorithm;
	p_algorithm = (void*)(new WindNetDetect());
	std::string net_bins = "./models/visdrone_1009-opt.bin";
	std::string net_paras = "./models/visdrone_1009-opt.param";
	int init_res = ((WindNetDetect*)p_algorithm)->init1(net_bins, net_paras);
	tmp = (WindNetDetect*)(p_algorithm);
	std::thread thrd_1(get_cam1);
	std::thread thrd_2(get_camusb);
	thrd_1.join();
	thrd_2.join();
	while (true)
	{
		std::cout << "Main Thread Display!" << std::endl;
		Sleep(3000);
	}
	return 0;
}

使用多線線程調(diào)用多個函數(shù)同步執(zhí)行模板如下:

#include <thread>
#include <mutex>
static std::mutex mutexk;
void func1() {
	while (capture1.isOpened()) {
		if (mutexk.try_lock()) {
			//我的算法
			my_func1();
            mutexk.unlock();
		}
	}
}
void func2() {
	while (capture2.isOpened()) {
		if (mutexk.try_lock()) {
			//我的算法
			my_func2();
            mutexk.unlock();
		}
	}
}
int main() {
	std::thread thrd_1(func1);
	std::thread thrd_2(func2);
	thrd_1.join();
	thrd_2.join();
	return 0;
}

在ubuntu中c++opencv多線程顯示圖片時出現(xiàn)Gdk-WARNING **: xx: Fatal IO error

解決辦法:

1、sudo apt install libx11-dev

2、在代碼中添加頭文件#include <X11/Xlib.h>

3、在創(chuàng)建線程之前添加XInitThreads()

4、在編譯的時候需要添加-lX11

參考鏈接:OpenCV視頻流C++多線程處理方法詳細分析

到此這篇關(guān)于C++雙線程調(diào)用網(wǎng)絡(luò)攝像頭與多線程調(diào)用多攝像頭同步執(zhí)行方法詳細講解的文章就介紹到這了,更多相關(guān)C++調(diào)用網(wǎng)絡(luò)攝像頭內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題

    解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題

    今天小編就為大家分享一篇解決C++ fopen按行讀取文件及所讀取的數(shù)據(jù)問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-07-07
  • 一篇文章讓你徹底明白c++11增加的變參數(shù)模板

    一篇文章讓你徹底明白c++11增加的變參數(shù)模板

    C++11的新特性--可變模版參數(shù)(variadic templates)是C++11新增的最強大的特性之一,它對參數(shù)進行了高度泛化,它能表示0到任意個數(shù)、任意類型的參數(shù),這篇文章主要給大家詳細介紹了關(guān)于c++11增加的變參數(shù)模板的相關(guān)資料,需要的朋友可以參考下
    2021-08-08
  • C/C++中四種常用查找算法的實現(xiàn)

    C/C++中四種常用查找算法的實現(xiàn)

    C語言作為一種強大的編程語言,提供了多種搜索算法的實現(xiàn)方式,本文將介紹C語言中的四種常見搜索算法并提供每種算法的簡單實現(xiàn)示例,需要的小伙伴可以參考下
    2023-11-11
  • C++多線程互斥鎖和條件變量的詳解

    C++多線程互斥鎖和條件變量的詳解

    這篇文章主要為大家詳細介紹了C++多線程互斥鎖和條件變量,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • C語言實現(xiàn)病例管理系統(tǒng)

    C語言實現(xiàn)病例管理系統(tǒng)

    這篇文章主要為大家詳細介紹了C語言實現(xiàn)病例管理系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • exit和atexit的區(qū)別詳細解析

    exit和atexit的區(qū)別詳細解析

    以下是對exit與atexit的區(qū)別進行了詳細的分析介紹,需要的朋友可以過來參考下
    2013-09-09
  • OpenCV霍夫變換(Hough Transform)直線檢測詳解

    OpenCV霍夫變換(Hough Transform)直線檢測詳解

    這篇文章主要為大家詳細介紹了OpenCV霍夫變換直線檢測的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • C程序結(jié)構(gòu)的入門

    C程序結(jié)構(gòu)的入門

    在我們學習 C 語言的基本構(gòu)建塊之前,讓我們先來看看一個最小的 C 程序結(jié)構(gòu),在接下來的章節(jié)中可以以此作為參考
    2021-06-06
  • opencv圖片的任意角度旋轉(zhuǎn)實現(xiàn)示例

    opencv圖片的任意角度旋轉(zhuǎn)實現(xiàn)示例

    這篇博客將介紹如何使用OpenCV旋轉(zhuǎn)圖像任意角度,實現(xiàn)各個角度的旋轉(zhuǎn),具有一定的參考價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-06-06
  • C語言中fopen()函數(shù)的使用方法示例詳解

    C語言中fopen()函數(shù)的使用方法示例詳解

    這篇文章主要介紹了C語言中fopen()函數(shù)的使用方法,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06

最新評論