C++ HTTP POST

.h

#pragma once



#ifndef HTTPCLIENT_H  
#define HTTPCLIENT_H  


#include <windows.h>
#include <WinInet.h> 
#include <string>  
using namespace std;




#define  IE_AGENT  _T("Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)")  
// 操作成功  
#define SUCCESS        0  
// 操作失败  
#define FAILURE        1  
// 操作超时
#define OUTTIME        2  
class HttpClient
{
public:
HttpClient();
~HttpClient();
int HttpGet(LPCTSTR strUrl, LPCTSTR strPostData, string &strResponse, std::vector<std::string> & vePostHeaders, const char * pSavePath = NULL);
int HttpPost(LPCTSTR strUrl, LPCTSTR strPostData, std::vector<std::string> & vePostHeaders, string &strResponse, const char * pSavePath = NULL);
int HttpPostEX(LPCTSTR strUrl, LPCTSTR strPostData, string &strResponse, const char * pInFilePath = NULL, const char * pOutFilePath = NULL);
int HttpPostEX(std::string strUrl, std::map<std::string, std::string> mapPostData, std::map<std::string, std::string> mapInFileName, string &strResponse, const char * pOutFilePath = NULL);


private:
int ExecuteRequest(LPCTSTR strMethod, LPCTSTR strUrl, LPCTSTR strPostData, string &strResponse);
void Clear();


};

#endif // HTTPCLIENT_H  


.cpp

#include "stdafx.h"
#include "HttpClient.h"
#include <Shlwapi.h>
#include <algorithm>
#include <cctype>
#include <functional>
#include "ParseUrl.h"


#define  BUFFER_SIZE       1024  


#define  NORMAL_CONNECT             INTERNET_FLAG_KEEP_CONNECTION  
#define  SECURE_CONNECT             NORMAL_CONNECT | INTERNET_FLAG_SECURE  
#define  NORMAL_REQUEST             INTERNET_FLAG_RELOAD | INTERNET_FLAG_DONT_CACHE   
#define  SECURE_REQUEST             NORMAL_REQUEST | INTERNET_FLAG_SECURE | INTERNET_FLAG_IGNORE_CERT_CN_INVALID


HttpClient::HttpClient()
{


}


HttpClient::~HttpClient()
{
Clear();
}


void HttpClient::Clear()
{


}


int HttpClient::ExecuteRequest(LPCTSTR strMethod, LPCTSTR strUrl, LPCTSTR strPostData, string &strResponse)
{
return SUCCESS;
}


int HttpClient::HttpGet(LPCTSTR strUrl, LPCTSTR strPostData, string &strResponse, std::vector<std::string> & vePostHeaders, const char * pSavePath)
{


PARSEDURL pu;
pu.cbSize = sizeof(pu);
HRESULT hr = ParseURL(strUrl, &pu);
if (SUCCEEDED(hr))
{
if (pu.nScheme != URL_SCHEME_HTTP && pu.nScheme != URL_SCHEME_HTTPS)
{
return FAILURE;
}
}


Uri url = Uri::Parse(strUrl);

// 建立会话
HINTERNET hInternet;
hInternet = InternetOpen(IE_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet == NULL)
return FAILURE;


// 建立连接
HINTERNET hConnect;
hConnect = InternetConnect(hInternet, url.Host.c_str(), atoi((CStringHelper::ws2s(url.Port)).c_str()),
L"", L"", INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);


if (hInternet == NULL)
{
InternetCloseHandle(hInternet);
return FAILURE;
}


std::wstring wstrObject = url.Path + url.QueryString;
HINTERNET httpFile;
httpFile = HttpOpenRequest(hConnect, L"GET", wstrObject.c_str(), HTTP_VERSION, NULL, 0, INTERNET_FLAG_NO_UI | INTERNET_FLAG_DONT_CACHE, 1);
if (httpFile == NULL)
{
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);


return FAILURE;
}


for (UINT i = 0; i < vePostHeaders.size(); i++)
{
std::string strHeader = vePostHeaders[i];
HttpAddRequestHeadersA(httpFile, strHeader.c_str(), strHeader.length(), HTTP_ADDREQ_FLAG_ADD);
}


#if 0
std::wstring wstrAddHeaders = L"Accept: *,*/*";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
wstrAddHeaders = L"Accept-Language: zh-cn";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
wstrAddHeaders = L"Content-Type: application/x-www-form-urlencoded";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
wstrAddHeaders = L"Accept-Encoding: gzip, deflate";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
#endif


HttpSendRequest(httpFile, NULL, NULL, 0, 0);

FILE *fp = NULL;
if (pSavePath)
{
fopen_s(&fp, pSavePath, "wb");
}


char buf[BUFFER_SIZE + 1] = { 0 };
DWORD buf_len = BUFFER_SIZE;
DWORD buf_read = BUFFER_SIZE;
DWORD buf_count = 0;
std::string strRawResponse;
while (1)
{
InternetReadFile(httpFile, buf, buf_len, &buf_read);
if (buf_read == 0) break;
buf[buf_read] = '\0';


if (pSavePath && fp)
{
fwrite(buf, 1, buf_read, fp);

else
{
strRawResponse += buf;
}


buf_count += buf_read;
memset(buf, 0, BUFFER_SIZE + 1);
}


if (fp)
{
fclose(fp);
}
strResponse = strRawResponse;


InternetCloseHandle(httpFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);


return SUCCESS;
}


int HttpClient::HttpPost(LPCTSTR strUrl, LPCTSTR strPostData, std::vector<std::string> & vePostHeaders, string &strResponse, const char * pSavePath)
{
PARSEDURL pu;
pu.cbSize = sizeof(pu);
HRESULT hr = ParseURL(strUrl, &pu);
if (SUCCEEDED(hr))
{
if (pu.nScheme != URL_SCHEME_HTTP && pu.nScheme != URL_SCHEME_HTTPS)
{
return FAILURE;
}
}


Uri url = Uri::Parse(strUrl);


// 建立会话
HINTERNET hInternet;
hInternet = InternetOpen(IE_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (hInternet == NULL)
return FAILURE;


// 建立连接
HINTERNET hConnect;
hConnect = InternetConnect(hInternet, url.Host.c_str(), atoi((CStringHelper::ws2s(url.Port)).c_str()),
L"", L"", INTERNET_SERVICE_HTTP, INTERNET_FLAG_PASSIVE, 0);


if (hInternet == NULL)
{
InternetCloseHandle(hInternet);
return FAILURE;
}


std::wstring wstrObject = url.Path + url.QueryString;
HINTERNET httpFile;
httpFile = HttpOpenRequest(hConnect, L"POST", wstrObject.c_str(), HTTP_VERSION, NULL, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_CACHE_WRITE, 0);
if (httpFile == NULL)
{
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);


return FAILURE;
}


for (UINT i=0; i<vePostHeaders.size(); i++)
{
std::string strHeader = vePostHeaders[i];
HttpAddRequestHeadersA(httpFile, strHeader.c_str(), strHeader.length(), HTTP_ADDREQ_FLAG_ADD);
}


#if 0
std::wstring wstrAddHeaders = L"Accept: *,*/*";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
wstrAddHeaders = L"Accept-Language: zh-cn";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
wstrAddHeaders = L"Content-Type: application/x-www-form-urlencoded";
// wstrAddHeaders = L"Content-Type: application/json;charset=UTF-8";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
wstrAddHeaders = L"Accept-Encoding: gzip, deflate";
HttpAddRequestHeaders(httpFile, wstrAddHeaders.c_str(), wstrAddHeaders.length(), HTTP_ADDREQ_FLAG_ADD);
#endif


std::wstring wstrPostData = strPostData;
std::string strPostData2 = CStringHelper::ws2s(wstrPostData);
DWORD dwSize = strPostData2.length();
HttpSendRequestA(httpFile, NULL, NULL, (LPVOID)strPostData2.c_str(), dwSize);


FILE *fp = NULL;
if (pSavePath)
{
fopen_s(&fp, pSavePath, "wb");
}


char buf[BUFFER_SIZE + 1] = { 0 };
DWORD buf_len = BUFFER_SIZE;
DWORD buf_read = BUFFER_SIZE;
DWORD buf_count = 0;
std::string strRawResponse;
while (1)
{
InternetReadFile(httpFile, buf, buf_len, &buf_read);
if (buf_read == 0) break;
buf[buf_read] = '\0';


if (pSavePath && fp)
{
fwrite(buf, 1, buf_read, fp);
}
else
{
strRawResponse += buf;
}


buf_count += buf_read;
memset(buf, 0, BUFFER_SIZE + 1);
}


if (fp)
{
fclose(fp);
}
strResponse = strRawResponse;


InternetCloseHandle(httpFile);
InternetCloseHandle(hConnect);
InternetCloseHandle(hInternet);


return SUCCESS;
}


BOOL UseHttpSendRequestDataToWeb(HINTERNET hRequest, std::map<std::string, std::string> mapPostData, std::map<std::string, std::string> mapInFileName, BOOL bUseHeader)
{
if (!hRequest)
return FALSE;


char szFormat[1024] = { 0 };
ULONGLONG   ullPostSize = 0;
std::string strKey = "";
std::string strValue = "";
std::string strFilePath = "";
std::string strFileName = "";
std::string strFormat = "";
std::map<std::string, std::string> mapPostFile;
std::vector<std::string> vecPostData;


std::map<std::string, std::string>::iterator it;
for (it = mapInFileName.begin(); it != mapInFileName.end(); it++)
{
strKey = it->first;
strValue = it->second;


FILE *fp = NULL;
fopen_s(&fp, strValue.c_str(), "rb");
if (NULL == fp)
{
continue;
}

fseek(fp, 0L, SEEK_END);
ullPostSize += ftell(fp);
fclose(fp);


strFileName = CStringHelper::GetFileName(strValue.c_str());
sprintf_s(szFormat, "-----------------------------7dd16d1320516\r\nContent-Disposition: form-data; name=\"%s\"; filename=\"%s\"\r\n\r\n", strKey.c_str(), strFileName.c_str());
strFormat = szFormat;
ullPostSize += strFormat.length();


mapPostFile.insert(make_pair(strValue, strFormat));
}


std::map<std::string, std::string>::iterator it2;
for (it2 = mapPostData.begin(); it2 != mapPostData.end(); it2++)
{
std::string strKey = it2->first;
std::string strValue = it2->second;


sprintf_s(szFormat, "-----------------------------7dd16d1320516\r\nContent-Disposition: form-data; name=\"%s\"\r\n\r\n\"%s\"\r\n", strKey.c_str(), strValue.c_str());
strFormat = szFormat;
ullPostSize += strFormat.length();


vecPostData.push_back(strFormat);
}




//此处是header和body的前置数据段,一般向WEB发送数据是不需要的(即:bUseHeader=FALSE)  
//因为模拟了通过web页面向服务器post数据,所以需要添加boundary(分隔符, 用于描述不同的数据名称、标识、data==)  
//模拟时,\r\n是需要的,个数是通过Fiddler2软件截获正常网页发送时为防止错才固定的  
//至于数字7dd16d1320516本来是随机值,但对于业务来说,此处仅仅是分割作用,无所谓了  
char szHeader[] = "Accept: *,*/*\r\nConnection: Keep-Alive\r\nContent-Type: application/octet-stream\r\nContent-Type: multipart/form-data; boundary=---------------------------7dd16d1320516\r\n";
char*   pchEnd = "\r\n-----------------------------7dd16d1320516--\r\n";
int     nEndLen = strlen(pchEnd);


//发送上传请求  
INTERNET_BUFFERSA   bufferIn = { 0 };
bufferIn.dwStructSize = sizeof(INTERNET_BUFFERSA);   //必须设置,否则出错  
bufferIn.lpcszHeader = szHeader;
bufferIn.dwHeadersLength = strlen(szHeader);
bufferIn.dwBufferTotal = ullPostSize + nEndLen;
if (!HttpSendRequestExA(hRequest, &bufferIn, NULL, 0, 0))
return FALSE;


const int   N_SizeEveryTime = 1024;
BYTE        bufData[N_SizeEveryTime] = { 0 };
DWORD       dwBytesRead = 0;
DWORD       dwBytesOut = 0;
DWORD       dwBytesOutAll = 0;
BOOL        bRet = TRUE;


for (UINT i = 0; i < vecPostData.size(); i++)
{
std::string strPostData = vecPostData[i];
bRet = InternetWriteFile(hRequest, strPostData.c_str(), strPostData.length(), &dwBytesOut);
if (!bRet)
return FALSE;


dwBytesOutAll += dwBytesOut;
}


std::map<std::string, std::string>::iterator it3;
for (it3 = mapPostFile.begin(); it3 != mapPostFile.end(); it3++)
{
strKey = it3->first;
strValue = it3->second;
bRet = InternetWriteFile(hRequest, strValue.c_str(), strValue.length(), &dwBytesOut);
if (!bRet)
return FALSE;


dwBytesOutAll += dwBytesOut;


FILE *fp = NULL;
fopen_s(&fp, strKey.c_str(), "rb");
if (NULL == fp)
{
return FALSE;
}


//读取并发送数据  
while (TRUE)
{
dwBytesRead = fread(bufData, 1, N_SizeEveryTime, fp);
if (dwBytesRead <= 0)
break;


//write数据  
bRet = InternetWriteFile(hRequest, bufData, dwBytesRead, &dwBytesOut);
if (!bRet)
return FALSE;


dwBytesOutAll += dwBytesOut;
}


fclose(fp);
}


//如果filename不为空,则发送表尾结束符  
if (bUseHeader)
{
bRet = InternetWriteFile(hRequest, pchEnd, nEndLen, &dwBytesOut);
if (!bRet)
return FALSE;


dwBytesOutAll += dwBytesOut;
}


//结束上传请求  
if (!HttpEndRequest(hRequest, NULL, 0, 0))
{
DWORD   dwErr = GetLastError();
return FALSE;
}


return dwBytesOutAll == bufferIn.dwBufferTotal;
}


//int HttpClient::HttpPostEX(LPCTSTR strUrl, LPCTSTR strPostData, string &strResponse, const char * pInFilePath, const char * pOutFilePath)
int HttpClient::HttpPostEX(std::string strUrl, std::map<std::string, std::string> mapPostData, std::map<std::string, std::string> mapInFileName, string &strResponse, const char * pOutFilePath)
{
const int   N_BufferSizeRead_Net = 1024;
BOOL        bRet = FALSE;
DWORD       dwErr = 0;
HINTERNET   hOpen = NULL;
HINTERNET   hConnect = NULL;
HINTERNET   hRequest = NULL;
int nRet = FAILURE;
do
{
PARSEDURLA pu;
pu.cbSize = sizeof(pu);
HRESULT hr = ParseURLA(strUrl.c_str(), &pu);
if (SUCCEEDED(hr))
{
if (pu.nScheme != URL_SCHEME_HTTP && pu.nScheme != URL_SCHEME_HTTPS)
{
break;;
}
}


Uri url = Uri::Parse(CStringHelper::s2ws(strUrl));
std::wstring wstrObject = url.Path + url.QueryString;


//Initializes an application's use of the WinINet functions.  
hOpen = InternetOpen(IE_AGENT, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
if (!hOpen)
goto EndFlag;


//Opens an File Transfer Protocol (FTP), Gopher, or HTTP session for a given site  
hConnect = InternetConnect(hOpen, url.Host.c_str(), atoi((CStringHelper::ws2s(url.Port)).c_str()), NULL, NULL, INTERNET_SERVICE_HTTP, NULL, NULL);
if (!hConnect)
goto EndFlag;


//Creates an HTTP request handle.  
TCHAR* szAccept[] = { _T("*/*"), NULL };
hRequest = HttpOpenRequest(hConnect, _T("POST"), wstrObject.c_str(), HTTP_VERSION/*NULL*/, NULL, /*NULL*/(LPCTSTR*)szAccept, INTERNET_FLAG_NO_CACHE_WRITE /*| INTERNET_FLAG_RELOAD /*| INTERNET_FLAG_KEEP_CONNECTION*/, 0);
if (!hRequest)
goto EndFlag;


if (UseHttpSendRequestDataToWeb(hRequest, mapPostData, mapInFileName, true))
{
//Retrieves header information associated with an HTTP request  
int nState = 0;
DWORD n = sizeof(nState);
::HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &nState, &n, 0);
// if (nState != 200)
// goto EndFlag;


char    chBuf[N_BufferSizeRead_Net] = { 0 };
DWORD   dwBytesRead = 0;


FILE *fp = NULL;
if (pOutFilePath)
{
fopen_s(&fp, pOutFilePath, "wb");
}


do
{
//读取上传完成后的返回结果  
memset(chBuf, 0, N_BufferSizeRead_Net);
if (InternetReadFile(hRequest, chBuf, N_BufferSizeRead_Net - 1, &dwBytesRead) && dwBytesRead > 0)
{
/// <读取保存返回的数据>
if (fp && nState == 200)
{
fwrite(chBuf, 1, dwBytesRead, fp);
}
else
{
strResponse += chBuf;
}
}
else
{
dwErr = GetLastError();
break;
}
} while (/*dwContentLen > 0 &&*/ dwBytesRead > 0);


if (fp)
{
fclose(fp);
}


nRet = SUCCESS;
}


EndFlag:
if (hRequest)
{
bRet = InternetCloseHandle(hRequest);
hRequest = NULL;
}
if (hConnect)
{
bRet = InternetCloseHandle(hConnect);
hConnect = NULL;
}
if (hOpen)
{
bRet = InternetCloseHandle(hOpen);
hOpen = NULL;
}
break;


} while (0);


return nRet;
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
cc是c是一c是一种c是一种编c是一种编程c是一种编程语c是一种编程语言c是一种编程语言。c是一种编程语言。它c是一种编程语言。它是c是一种编程语言。它是一c是一种编程语言。它是一种c是一种编程语言。它是一种通c是一种编程语言。它是一种通用c是一种编程语言。它是一种通用、c是一种编程语言。它是一种通用、高c是一种编程语言。它是一种通用、高级c是一种编程语言。它是一种通用、高级别c是一种编程语言。它是一种通用、高级别的c是一种编程语言。它是一种通用、高级别的编c是一种编程语言。它是一种通用、高级别的编程c是一种编程语言。它是一种通用、高级别的编程语c是一种编程语言。它是一种通用、高级别的编程语言c是一种编程语言。它是一种通用、高级别的编程语言,c是一种编程语言。它是一种通用、高级别的编程语言,还c是一种编程语言。它是一种通用、高级别的编程语言,还是c是一种编程语言。它是一种通用、高级别的编程语言,还是一c是一种编程语言。它是一种通用、高级别的编程语言,还是一种c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。Cc是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于197c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。Cc是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。Cc是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括Cc是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括C++c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括C++、c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括C++、Javac是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括C++、Java和c是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括C++、Java和Pythonc是一种编程语言。它是一种通用、高级别的编程语言,还是一种结构化编程语言。C语言由贝尔实验室的丹尼斯·里奇于1972年发明。C语言很流行,因为它具有灵活、高效和可移植的特性。C语言的许多概念和语法被其他编程语言采用和模仿,包括C++、Java和Python。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值