C++ socket实现miniFTP

本文实例为大家分享了C++ socket实现miniFTP的方法,供大家参考,具体内容如下

客户端:

服务端:

建立连接

        连接使用 TCP 连接,服务器和客户端分别创建自己的套接字一端,服务器等待连接,客户端发起连接(并指定服务器 ip)。在两者端口号一致且不被占用的情况下,连接建立。
        在整个过程中,服务器对每一个来访的客户端建立一个连接,在客户未请求与服务器断开时,该连接一直存在,用户可以不断向服务器发出请求。(持久性、流水线型连接 )
        客户端断开后,关闭客户端的套接字部分,服务器继续等待新的连接。服务器一次只能处理一个客户端的连接,不支持并发访问。

PDU 格式

        由于 ftp 应当支持几乎任意类型文件,而几乎所有类型文件都能用二进制来解析,所以我们采用了二进制的格式来读取以及写入文件。在整个过程中,我们并不关心文件的具体内容,也无需在程序中解析文件,而是将其当作数据流看待。
        受到缓存区大小的限制,我们无法一次性传输整个文件,所以我们将文件按缓存区大小拆分成数据包分批发送,我们可以将数据及时从缓存区写入文件,这样就让出了缓存区空间。数据包仅仅包含数据,不包含头部或尾部信息。
        此外,接收文件时,recv()函数将会循环调用,因此,我们需要一个信号来通知什么时候发送完毕。
        一个想法是发送终止信号,这是可行的,但更好的方法是在一开始发送文件总字节数,让接收方根据剩余字节大小判断什么时候接收完毕。因为在写入文件时,我们需要指定写入的字节数,尤其是在发来的数据流字节数不等于缓冲区大小时。写入字节数的错误会导致文件受损。

接收确认

        我们知道 TCP 是可靠传输协议,它采取了一系列措施来保证传输不会出错。所以在使用 TCP 连接时,我们相信数据在链路层上没有出差错,它一定会成功发送到对方手上。但是在客户端接收服务器发来的文件的时候,我们仍然需要服务器发来确认信息。原因在于,虽然我们可以保证链路层不出错,但是我们无法保证应用层不出错。例如,客户端可能会给出错误的文件名,因为接收不到服务器发来的信息,所以会陷入空等状态。

ftpClient.h

#pragma  
#include<winsock.h> 
class ftpClient 
{ 
private: 
  enum { 
    SERVER_PORT = 9999,BUFFER_SIZE = 4096 
  }; 
  sockaddr_in serverChannel; 
  char buffer[BUFFER_SIZE]; 
  int serverSocket; 
  int clientSocket; 
  bool isConnect; 
  char name[50]; 
 
  bool getFile(); 
  bool putFile(); 
  bool acknowledge(); 
  bool sendRequest(char* instruction); 
  bool connect2Host(const char* hostName); 
  bool getWorkDir(); 
 
public: 
  ftpClient(); 
  ~ftpClient(); 
  void start(); 
}; 

ftpClient.cpp

#define _CRT_SECURE_NO_WARNINGS 
#include"ftpClient.h" 
#include<cstdio> 
#include<io.h> 
#include<cstring> 
#include<fstream> 
 
ftpClient::ftpClient() 
{ 
  WORD wVersionRequested; 
  WSADATA wsaData; 
  int ret; 
 
  //WinSock初始化: 
  wVersionRequested = MAKEWORD(2,2);//希望使用的WinSock DLL的版本 
  ret = WSAStartup(wVersionRequested,&wsaData); 
  if (ret != 0) 
  { 
    printf("WSAStartup() failed!\n"); 
  } 
  //确认WinSock DLL支持版本2.2: 
  if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) 
  { 
    WSACleanup(); 
    printf("Invalid Winsock version!\n"); 
  } 
  isConnect = false; 
} 
 
void ftpClient::start() 
{ 
  char c[100]; 
  char d[100]; 
  printf("这里是FTP客户端,您可以输入help查看操作方法,输入quit退出客户端\n"); 
 
  while (1) { 
    scanf("%s",c); 
    if (strcmp(c,"help") == 0) { 
      printf("get [fileName]  --  下载文件\n" 
        "put [fileName]  --  上传文件\n" 
        "ftp [ip]     --  登录FTP\n" 
        "pwd        --  显示服务器当前工作文件夹\n" 
        "cd [dirName]   --  更改当前文件夹\n" 
        "close       --  关闭与当前ftp的连接\n" 
        "quit       --  退出客户端\n" 
        ); 
    } 
    else if (strcmp(c,"get") == 0) { 
      scanf("%s",d); 
      strcat(c," "); 
      strcat(c,d); 
      if (!isConnect) { 
        printf("you haven't connected to any server!\n"); 
      } 
      else sendRequest(c); 
    } 
    else if (strcmp(c,"put") == 0) { 
      scanf("%s","ftp") == 0) { 
      scanf("%s",d); 
      if (!isConnect&&connect2Host(d)) { 
        isConnect = true; 
      } 
      else if(isConnect){ 
        printf("you have already connected to server\n" 
          "please close the connection before connect to a new server\n"); 
      } 
    } 
    else if (strcmp(c,"pwd") == 0) { 
      if (!isConnect) { 
        printf("you haven't connected to any server!\n"); 
      } 
      else sendRequest(c); 
    } 
    else if (strcmp(c,"cd") == 0) { 
      scanf("%s","quit") == 0) { 
      if (isConnect) { 
        strcpy(c,"close"); 
        isConnect = false; 
        send(clientSocket,c,strlen(c) + 1,0); 
        closesocket(clientSocket); 
      } 
      break; 
    } 
    else if (strcmp(c,"close") == 0) { 
      if (isConnect) { 
        isConnect = false; 
        send(clientSocket,0); 
        closesocket(clientSocket); 
      } 
    } 
    else { 
      printf("syntex error\n"); 
    } 
  } 
} 
 
bool ftpClient::connect2Host(const char* hostName) 
{ 
  //创建socket 
  clientSocket = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 
 
  if (clientSocket < 0) { 
    printf("cannot create socket\n"); 
    return false; 
  } 
  else printf("successfully create socket\n"); 
  memset(&serverChannel,sizeof(serverChannel));//初始化为0 
 
  serverChannel.sin_family = AF_INET;//channel协议家族AF_INET 
  serverChannel.sin_addr.S_un.S_addr = inet_addr(hostName);//地址 
  serverChannel.sin_port = htons(SERVER_PORT);//服务器端口 
 
                        //建立连接 
  serverSocket = connect(clientSocket,(sockaddr*)&serverChannel,sizeof(serverChannel)); 
 
  if (serverSocket < 0) { 
    printf("cannot connect to the host\n"); 
    return false; 
  } 
  else { 
    printf("successfully connect to the host\n"); 
    return true; 
  } 
} 
 
bool ftpClient::sendRequest(char* instruction) 
{ 
  int r = send(clientSocket,instruction,strlen(instruction) + 1,0); 
  if (r == SOCKET_ERROR) { 
    printf("request failed\n"); 
    return false; 
  } 
  else { 
    printf("request success\n"); 
    char opt[5]; 
    int i = 0,j = 0; 
    while (instruction[i] != ' '&&instruction[i] != '\0') { 
      opt[i] = instruction[i]; 
      i++; 
    } 
    opt[i] = '\0'; 
    i++; 
    while (instruction[i] != '\0') { 
      name[j] = instruction[i]; 
      i++,j++; 
    } 
    name[j] = '\0'; 
    if (strcmp(opt,"get") == 0) { 
      if (getFile()) { 
        printf("successfully download\n"); 
      } 
      else printf("download failed\n"); 
    } 
    else if (strcmp(opt,"put") == 0) { 
      if (putFile()) { 
        printf("successfully upload\n"); 
      } 
      else printf("upload failed\n"); 
    } 
    else if (strcmp(opt,"pwd") == 0) { 
      if (!getWorkDir()) 
        printf("get work directory failed\n"); 
    } 
    else if (strcmp(opt,"cd") == 0) { 
      printf("operation finished\n"); 
    } 
    else { 
      printf("syntex error\n"); 
      return false; 
    } 
    return true; 
  } 
} 
 
bool ftpClient::getFile() 
{ 
  memset(buffer,sizeof(buffer)); 
  int ret; 
  char length[20]; 
  ret = recv(clientSocket,length,sizeof(length),0); 
  if (ret == SOCKET_ERROR) { 
    return false; 
  } 
  else if (strcmp(length,"NAK") == 0) { 
    return false; 
  } 
  int size = atoi(length); 
  std::ofstream out; 
 
  out.open(name,std::ios::binary); 
  if (!out) { 
    printf("cannot save the file\n"); 
    return false; 
  } 
  while (size>0) { 
    ret = recv(clientSocket,buffer,BUFFER_SIZE,0); 
    int s = size < BUFFER_SIZE ? size : BUFFER_SIZE; 
    if (ret == SOCKET_ERROR) { 
      out.close(); 
      return false; 
    } 
    else if (strcmp(buffer,"NAK") == 0) { 
      out.close(); 
      return false; 
    } 
    else { 
      out.write(buffer,s); 
    } 
    size -= BUFFER_SIZE; 
  } 
  out.close(); 
  return acknowledge(); 
} 
 
bool ftpClient::putFile() 
{ 
  std::ifstream in; 
  //打开文件 
  in.open(name,std::ios::binary); 
  if (!in) { 
    printf("cannot open the file\n"); 
    return false; 
  } 
  memset(buffer,sizeof(buffer)); 
  //得到文件的字节数 
  in.seekg(0,std::ios_base::end); 
  int sp = in.tellg(); 
  int total_size = 0; 
  int r; 
  char length[20]; 
  sprintf(length,"%d",sp); 
 
  //发送字节 
  r = send(clientSocket,0); 
  if (r == SOCKET_ERROR) { 
    return false; 
  } 
  while (sp > 0) { 
    in.clear(); 
    in.seekg(total_size,std::ios_base::beg); 
    memset(buffer,sizeof(buffer)); 
    //读取文件 
    in.read(buffer,sizeof(buffer)); 
    int size = sp < BUFFER_SIZE ? sp : BUFFER_SIZE; 
    total_size += size; 
    //发送文件 
    r = send(clientSocket,size,0); 
 
    sp -= size; 
    if (r == SOCKET_ERROR) { 
      in.close(); 
      return false; 
    } 
  } 
  in.close(); 
} 
 
bool ftpClient::getWorkDir() { 
  printf("getWorkDir\n"); 
  memset(buffer,0); 
  if (ret == SOCKET_ERROR) { 
    return false; 
  } 
  int size = atoi(length); 
  while (size>0) { 
    ret = recv(clientSocket,0); 
    if (ret == SOCKET_ERROR) { 
      return false; 
    } 
    else { 
      printf("%s",buffer); 
    } 
    size -= BUFFER_SIZE; 
  } 
  return true; 
} 
 
bool ftpClient::acknowledge() 
{ 
  int ret = recv(clientSocket,0); 
  if (ret > 0) { 
    if (strcmp(buffer,"NAK") == 0)return false; 
    else if (strcmp(buffer,"ACK") == 0)return true; 
  } 
} 
 
ftpClient::~ftpClient() 
{ 
  if (isConnect) { 
    isConnect = false; 
    char c[6]; 
    strcpy(c,"close"); 
    send(clientSocket,0); 
    closesocket(clientSocket); 
  } 
} 

main.cpp

#define _CRT_SECURE_NO_WARNINGS 
#define _WINSOCK_DEPRECATED_NO_WARNINGS 
#pragma(lib,"ws2_32.lib") 
#include"ftpClient.h" 
#include<stdio.h> 
 
int main() 
{ 
  ftpClient a; 
  a.start(); 
  return 0; 
} 

ftpServer.h

#pragma once 
#include<winsock.h> 
 
class ftpServer 
{ 
private: 
  enum { 
    SERVER_PORT = 9999,BUFFER_SIZE = 4096,QUEUE_SIZE = 10 
  }; 
  char buffer[BUFFER_SIZE]; 
  sockaddr_in serverChannel; 
  char name[50]; 
  char workDir[100]; //store like C:\Users MARK:字符串末没有斜线!! 
  int serverSocket; //socket 
  int clientSocket; 
  bool sendFile(); 
  bool receiveFile(); 
  bool doPwd(); 
  bool doCd(); 
  bool isValidPath(char* path); 
public: 
  ftpServer(); 
  bool start();//开启服务器 
}; 

ftpServer.cpp

#define _CRT_SECURE_NO_WARNINGS 
 
#include"ftpServer.h" 
#include<cstdio> 
#include<cstdlib> 
#include<fstream> 
#include<cstring> 
 
ftpServer::ftpServer() 
{ 
  WORD wVersionRequested; 
  WSADATA wsaData; 
  int ret; 
 
  //WinSock初始化: 
  wVersionRequested = MAKEWORD(2,&wsaData); 
  if (ret != 0) 
  { 
    printf("WSAStartup() failed!\n"); 
  } 
  //确认WinSock DLL支持版本2.2: 
  if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2) 
  { 
    WSACleanup(); 
    printf("Invalid Winsock version!\n"); 
  } 
  //workDir初始化为当前路径 
  system("cd > tempFile"); 
  std::ifstream in("tempFile",std::ifstream::in); 
  in >> workDir; 
  in.close(); 
} 
 
bool ftpServer::start() 
{ 
  int on = 1; 
 
  //初始化服务器 
  memset(&serverChannel,sizeof(serverChannel)); 
  serverChannel.sin_family = AF_INET; 
  serverChannel.sin_addr.s_addr = htonl(INADDR_ANY); 
  serverChannel.sin_port = htons(SERVER_PORT); 
 
  //创建套接字 
  this->serverSocket = socket(AF_INET,IPPROTO_TCP); 
  if (serverSocket < 0) { 
    printf("cannot create socket\n"); 
    return false; 
  } 
  else printf("successfully create socket\n"); 
  setsockopt(serverSocket,SOL_SOCKET,SO_REUSEADDR,(char*)&on,sizeof(on)); 
 
  //绑定 
  int b = bind(serverSocket,sizeof(serverChannel)); 
  if (b < 0) { 
    printf("bind error\n"); 
    return false; 
  } 
  else printf("successfully bind\n"); 
  //监听 
  int l = listen(serverSocket,QUEUE_SIZE); 
  if (l < 0) { 
    printf("listen failed\n"); 
    return false; 
  } 
  else printf("successfully listen\n"); 
  int len = sizeof(serverChannel); 
  //服务器等待连接 
  while (1) { 
    printf("waiting for connection...\n"); 
    //接受一个连接 
    clientSocket = accept(serverSocket,&len); 
    if (clientSocket < 0) { 
      printf("accept failed\n"); 
    } 
    else { 
      printf("successfully connect\n"); 
      while (1) { 
        memset(buffer,sizeof(buffer)); 
        int ret; 
 
        ret = recv(clientSocket,0); 
 
        if (ret == SOCKET_ERROR) { 
          printf("receive failed\n"); 
        } 
        else { 
          char opt[50]; 
          printf("successfully receive\n"); 
          int i = 0,j = 0; 
          printf("buffer = %s\n",buffer); 
          while (buffer[i] != ' '&&buffer[i] != '\0') { 
            opt[i] = buffer[i]; 
            i++; 
          } 
          opt[i] = '\0'; 
          if (buffer[i] != '\0') { 
            i++; 
          } 
          while (buffer[i] != '\0') { 
            name[j] = buffer[i]; 
            i++,j++; 
          } 
          name[j] = '\0'; 
 
          if (strcmp(opt,"get") == 0) { 
            char ret[4]; 
            if (!sendFile()) { 
              strcpy(ret,"NAK"); 
              send(clientSocket,ret,sizeof(ret),0); 
            } 
            else { 
              strcpy(ret,"ACK"); 
              send(clientSocket,0); 
            } 
          } 
          else if (strcmp(opt,"put") == 0) { 
            receiveFile(); 
          } 
          else if (strcmp(opt,"pwd") == 0) { 
            doPwd(); 
          } 
          else if (strcmp(opt,"cd") == 0) { 
            doCd(); 
          } 
          else if (strcmp(opt,"close") == 0) { 
            break; 
          } 
          else { 
            printf("syntex error\n"); 
          } 
        } 
      } 
    } 
  } 
  return true; 
} 
 
bool ftpServer::sendFile() 
{ 
  std::ifstream in; 
  char path[100]; 
  strcpy(path,workDir); 
  strcat(path,"\\"); 
  strcat(path,name); 
 
  in.open(path,sizeof(buffer)); 
  in.seekg(0,sp); 
   
  r = send(clientSocket,0); 
 
  if (r == SOCKET_ERROR) { 
    printf("send failed\n"); 
    return false; 
  } 
  else { 
    printf("send success\n"); 
  } 
 
  while (sp > 0) { 
    in.clear(); 
    in.seekg(total_size,sizeof(buffer)); 
    in.read(buffer,sizeof(buffer)); 
    int size = sp < BUFFER_SIZE ? sp : BUFFER_SIZE; 
    total_size += size; 
    r = send(clientSocket,0); 
 
    sp -= size; 
    if (r == SOCKET_ERROR) { 
      printf("send failed\n"); 
      return false; 
    } 
    else { 
      printf("send success\n"); 
    } 
  } 
  in.close(); 
  return true; 
} 
 
bool ftpServer::receiveFile() 
{ 
  char path[100]; 
  strcpy(path,name); 
  memset(buffer,0); 
  if (ret == SOCKET_ERROR) { 
    printf("receive failed\n"); 
    return false; 
  } 
  else { 
    printf("successfully receive\n"); 
  } 
  int size = atoi(length); 
  std::ofstream out; 
 
  out.open(path,std::ios::binary); 
  if (!out) { 
    printf("cannot save the file\n"); 
    return false; 
  } 
  while (size>0) { 
    int s = size < BUFFER_SIZE ? size : BUFFER_SIZE; 
    ret = recv(clientSocket,0); 
    if (ret == SOCKET_ERROR) { 
      printf("receive failed\n"); 
      break; 
    } 
    else { 
      printf("successfully receive\n"); 
      out.write(buffer,s); 
    } 
    size -= BUFFER_SIZE; 
  } 
  out.close(); 
  return true; 
} 
 
bool ftpServer::doPwd() { 
  char temCMD[150]; 
  memset(temCMD,sizeof(temCMD)); 
  strcat(temCMD,"echo "); 
  strcat(temCMD,workDir); 
  strcat(temCMD," > tempFile"); 
  system(temCMD); 
  memset(temCMD,"dir /b "); 
  strcat(temCMD," >> tempFile"); 
  system(temCMD); 
 
  std::ifstream in("tempFile",std::fstream::in); 
  if (!in) { 
    printf("cannot open the file\n"); 
    return false; 
  } 
  memset(buffer,sp); 
  r = send(clientSocket,0); 
 
  if (r == SOCKET_ERROR) { 
    printf("send failed\n"); 
    return false; 
  } 
  else { 
    printf("send success\n"); 
  } 
  while (sp > 0) { 
    in.clear(); 
    in.seekg(total_size,sizeof(buffer)); 
    int size = sp < BUFFER_SIZE ? sp : BUFFER_SIZE; 
    total_size += size; 
    printf("transfer size = %d\n",total_size); 
    r = send(clientSocket,0); 
 
    sp -= size; 
    if (r == SOCKET_ERROR) { 
      printf("send failed\n"); 
      return false; 
    } 
    else { 
      printf("send success\n"); 
    } 
  } 
  in.close(); 
  return true; 
} 
 
bool ftpServer::isValidPath(char* path) { 
  char temCMD[100]; 
  memset(temCMD,"cd "); 
  strcat(temCMD,path); 
  int res = system(temCMD); 
  return res == 0; 
} 
 
bool ftpServer::doCd() { 
  for (int i = 0; name[i] != '\0'; ++i) { 
    if (name[i] == '/') 
      name[i] = '\\'; 
  } 
  if (name[0] == '.'&&name[1] == '.') { 
    char temDir[100]; 
    strcpy(temDir,workDir); 
    for (int i = sizeof(temDir); i >= 0; --i) { 
      if (temDir[i] == '\\') { 
        temDir[i] = '\0'; 
        break; 
      } 
    } 
    strcat(temDir,name + 2); 
    if (isValidPath(temDir)) { 
      strcpy(workDir,temDir); 
    } 
    else { 
      return false; 
    } 
  } 
  else if (name[0] == '.'&&name[1] != '.') { 
    char temDir[100]; 
    strcpy(temDir,workDir); 
    strcat(temDir,name + 1); 
    if (isValidPath(temDir)) { 
      strcpy(workDir,temDir); 
    } 
    else { 
      return false; 
    } 
  } 
  else if (name[1] == ':') { 
    if (isValidPath(name)) { 
      strcpy(workDir,name); 
    } 
    else { 
      return false; 
    } 
  } 
  else { 
    char temDir[100]; 
    strcpy(temDir,"\\"); 
    strcat(temDir,name); 
    if (isValidPath(temDir)) { 
      strcpy(workDir,temDir); 
    } 
    else { 
      return false; 
    } 
  } 
  return true; 
} 

main.cpp

#include"ftpServer.h" 
#pragma(lib,"ws2_32.lib") 
int main() 
{ 
 ftpServer f; 
 f.start(); 
} 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程小技巧。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读315次。之前用C语言编过链表,这几天突然想用C++编一下链表,搞了大半天才搞出来,所以就赶紧整理一下记录下来,省的万一时间长了找不到代码哈哈。一、链表代码1、Node.h文件代码#pragma onceclass Node{public: int ID; char alph; Node* next; Node(int ID,char alph); ~Node();private:..._if(current->id==id)
文章浏览阅读219次。碰到问题就要记录下来,防止遗忘吧。文章目录一、VS中的命令行参数二、内联函数和宏三、初始化和赋值一、VS中的命令行参数今天在运行代码的时候,碰都了下面的情况: // 解析命令行参数 if (pcl::console::find_argument (argc, argv, "-h") >= 0) { printUsage (argv[0]); return 0; }..._"if (pcl::console::find_argument(argc, argv, "-f") >= 0)怎么输入参数"
文章浏览阅读1.8k次,点赞11次,收藏37次。因为自己对决策树的机制非常的好奇,所以就研究了一下决策树的ID3算法,在这也做一篇笔记记录一下过程。文章目录一、什么是决策树?二、信息增益2.1信息熵2.1.1定义2.1.2演变2.2信息增益三、ID3算法实现四、小结一、什么是决策树?这个问题是我从一开始就有的疑问,什么是决策树?在看了一些资料之后,因为没有看到书上给出具体定义,所以按照我自己的理解决策树就是通过一个个“决策”而构建的一种树状结构,而且决策树的整个处理机制非常类似于我们人类在面临决策问题时的处理机制,这也可能就是其名字的由来。决_c++id3
文章浏览阅读492次。C++ 设计模式之策略模式
文章浏览阅读683次。我也算是个C++的小白,对于C++中的谓语我第一时间就想到了C#中的委托,但两者又不尽相同,所以想写一篇笔记记录一下。文章目录一、什么是谓语?二、使用谓语一、什么是谓语?谓语是一个可调用的表达式,其返回的结果可以作为条件的值,在C++中其实就是向算法传递函数。这和C#中的委托的概念其实是一样的,都是将函数作为参数进行传递。C++标准库中的谓语主要有两类:一元谓语和二元谓语,也就是有的算法只能..._谓语句 c++
文章浏览阅读225次。又看了一遍操作符的东西,感觉之前对操作符的理解还停留在很浅的认知上(仅仅会用哈哈),所以做一下笔记来加深一下印象。文章目录一、为什么会有操作符重载?二、操作符重载作用的对象一、为什么会有操作符重载?如果要回答这个问题,我们其实应该仔细想一下如果没有操作符重载会怎样呢?这其实很容易就联想到了C语言,因为他就没有操作符重载这一说。虽然C语言中没有类class这一概念,但是他有着和类及其相似的结构..._6-6 我的朋友 - c/c++ 操作符重载分数 15作者 海洋饼干叔叔单位 重庆大学实现frie
文章浏览阅读216次。因为之前碰到了很多关于C++上的问题,现在整理并记录一下。文章目录一、引用一、引用在C++中,引用就是给对象起了另一个名字,也就是“对象别名”。感觉和什么东西很相似,仔细一想不就是类型别名“typedef”吗哈哈。它其实是和原对象形成了一种绑定的一种关系,..._vc++6.0报错:returning address of local
文章浏览阅读565次。因为一直好奇预处理器的工作机制,所以就查了查书,做一下自己看完书之后的笔记。文章目录一、预处理器的作用一、预处理器的作用_c语言预处理器作用
文章浏览阅读1.8k次,点赞3次,收藏10次。最近特别查阅了一下关于C++文件的输入/输出的资料,整理了一下就写一下笔记。文章目录一、什么是流二、什么是缓冲区三、代码实现文件IO3.1 使用文件流对象读取数据3.2重定向一、什么是流当前的计算机具有很多种设备,但是无论是哪种设备都要与数据和信息进行打交道,所以这就牵扯到设备与数据之间的I/O操作。而每种设备又有着不同的特性和操作协议,由于过于复杂,所以我们一般是不会和这些通信细节打交道的..._c++ inpath
文章浏览阅读4.8k次,点赞6次,收藏29次。因为要使用到C++的动态链接库,所以就特意网上找了一下资料实现了一下。文章目录一、lib与dll文件二、创建dll文件三、dll隐式链接四、显式链接五、小结一、lib与dll文件之前我一直以为动态链接库就是指dll文件,这也是C#给我造成的一种印象,因为在C#中建立的类库文件都是dll文件,而且只要简单引用就可以了,但是C++却并不是这样的,这可能是因为C#隐藏了一些细节的缘故吧。在C++中共有两种库模式,一种是包含lib和dll两种文件,这种情况下其中的lib文件包含了函数所在的dll文件和dl_c++调用动态链接库
文章浏览阅读973次。因为遇到了一这个操作符的问题,所以记录一下出现的问题*~*。一、问题描述二、产生原因因为也是第一次出现这个问题,所以就到网上查了一些资料和书籍,现在倒也大概理解这个错误出现的原因了。有时候举个例子可能更容易理解为啥会出现这个错误,就拿一本书中的例子来说一下,如下所示:template<class T> class NamedObject { public: NamedObject(std::string& nameVal, const T objectVal) __copy_assign报错
C语言中的单向链表可以解决数组和结构体在使用时的内存连续性问题,同时还能动态地调整长度。本文介绍了单向链表的结构和基本操作,并给出了一个简单的示例代码。
文章浏览阅读2.3k次。区分'0'、"0"、0、''_0和
文章浏览阅读5.8k次,点赞4次,收藏8次。C语言函数指针详解,微剖本质_c语言指针函数
数组指针和指针数组是代码中常见的定义形式。虽然它们的语法类似,但含义完全不同。对于一维数组而言,数组名即为首元素的地址,不需要取址即可赋值给指针。而对于二维数组,数组名代表首行元素的地址,可以看作是一个指针数组,需要使用取址操作。
文章浏览阅读297次。总结刚入门的新同学C语言编程常见的低级错误
文章浏览阅读1.5w次,点赞12次,收藏70次。C语言 数组指针详解_c语言数组指针
文章浏览阅读306次。cJson常用接口总结并测试_用于测试的json接口
本篇文章和大家了解一下C语言中pthread_exit()函数实现终止线程的方法。有一定的参考价值,有需要的朋友可以参考一下,希望对大家有所帮助。多线程编程中,线程...
本教程操作系统:windows10系统、c99版本、DELL G3电脑。 C语言是一门强大的编程语言,它允许我们对不同的数据类型进行各种运算和操作。但是有时候,我们需要将一个数据类型转换为另一个数据类型。这就是强制类型转