为什么会报这个错误呢

为什么报了这个错误

这是我的client文件、
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
int  SendtoServ(const char* mypath)
{
#if 1
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    char sendBuff[1000]{};
    wVersionRequested = MAKEWORD(2, 2);
    // 初始化套接字库
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        return err;
    }
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        WSACleanup();
        system("pause");
        return -1;
    }
#endif
    printf("fun sentoserv\n");
    SOCKET sockClie = socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == sockClie)
    {
        printf("socket errorNum = %d\n", GetLastError());
        system("pause");
        return -1;
    }
    //配置要连接的服务器
    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    //连接服务器
    if (SOCKET_ERROR == connect(sockClie, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR )))
    {
        printf("connect errorNum = %d\n", GetLastError());
        system("pause");
        return -1;
    }
    //读取文件内容
    FILE* fp = fopen(mypath, "rb");
    int len = fread(sendBuff, 1, 1000, fp);
    fclose(fp);
    // 发数据 
    int iLen = send(sockClie, (char*)sendBuff, 1000, 0);
    if (iLen<0)
    {
        printf("send error:%d", GetLastError());
        system("pause");
        return -1;
    }
    //关闭socket
    closesocket(sockClie);
    WSACleanup();
    return 0;
}
int  getFile(const char* filepath)
{
    //WIN32_FIND_DATA是一个结构体,可用来表示文件
    WIN32_FIND_DATA FindFileData;
    //文件、键盘、鼠标等都是通过句柄来标识
    HANDLE hListFile;
    //首先找到第一个文件,调用API findfirstfile,
    //MAX_PATH系统定义的一个宏,表示260
    char szFilePath[MAX_PATH]{};
    //strcpy字符串复制函数,strcat截断函数
    strcpy( szFilePath,filepath );
    strcat(szFilePath, "\\*");
    hListFile=FindFirstFile(szFilePath, &FindFileData);

    //循环遍历所有文件,如果FindNextFile返回值为0,即找不到下个文件,退出循环
    do 
    {
        char mypath[MAX_PATH]{};
        strcpy(mypath, filepath);
        strcat(mypath, FindFileData.cFileName);
        if (strstr(mypath,".txt"))
        {
            SendtoServ(mypath);
            printf("mypath==%s\n", mypath);
        }
    } while (FindNextFile(hListFile, &FindFileData));

    return 0;
}
int main()
{
    //定义一个函数,用来遍历未见
    getFile("C:\\Users\\zozoz\\Desktop\\woshizhu");
    system("pause");
    return 0;
}
这是我的server文件
#include <stdio.h>
#include <windows.h>
#pragma comment(lib, "ws2_32.lib")
#define  MAX_SIZE  100000
//写一个错误函数,打印错误码的控制台函数,打印后,直接退出
void errorhanding(const char* msg)
{
    fputs(msg, stderr);//stderr和getlasterror差不多,都是错误码
    fputc('\n', stderr);
    system("pause");
    exit(1);

}
int main()
{
#if 1
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    char MSG[MAX_SIZE]{0};
    wVersionRequested = MAKEWORD(2, 2);
    // 初始化套接字库
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        errorhanding("WSAStartup error");
        system("pause");
    }
    if (LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2)
    {
        printf("LOBYTE error:  %d\n", GetLastError());
        WSACleanup();
        errorhanding("LOBYTE error");
        system("pause");
        return -1;
    }
#endif
    SOCKET servsock =socket(PF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET== servsock)
    {
        errorhanding("servsock error");
    }


    SOCKADDR_IN addrSrv;
    addrSrv.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addrSrv.sin_family = AF_INET;
    addrSrv.sin_port = htons(6000);
    // 3 分配电话号码
    // 绑定套接字到本地 IP 地址,端口号 6000
    if (SOCKET_ERROR == bind(servsock, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR )))
    {
        errorhanding("bind  error");
    }
    // 4、监听 listen
    if (SOCKET_ERROR == listen(servsock, 5))
    {
        errorhanding("listen  error");
    }
    // 5、拿起话筒,准备通话
    SOCKADDR_IN addrCli;
    int len = sizeof(SOCKADDR_IN);
    int strlen{};
    SOCKET cliesock;
    for (int i=0;i<1000;i++)
    {
        cliesock = accept(servsock, (SOCKADDR*)&addrCli, &len);
        if (SOCKET_ERROR == cliesock)
        {
            errorhanding("accept  error");
        }
        memset(MSG, 0, MAX_SIZE);
        while ((strlen=recv(cliesock,MSG,MAX_SIZE,0))!=0)
        {
            printf("Server msg=%s\n", MSG);
        }
        closesocket(cliesock);
    }
    closesocket(servsock);
    WSACleanup();
    return 0;
}

报错内容: Microsoft Visual C++ Runtime Library
Debug Assertion Failed!
Program: C:\Users\zozoz\source\repos\文件窃取\Debug\steal-client.exeFile: minkernel\crtsjucrt\srclappcrt\stdio\fread.cpp
Line: 48
Expression: stream != nullptr
For information on how your program can cause an assertionfailure, see the visual C++ documentation on asserts.
(Press Retry to debug the application)

报错不是通过VS报错的,而是直接弹出了一个警告框,具体内容已经写在代码最后了,望解答

img

以下答案由GPT-4.5Plus大模型(语音)与博主A努力中.......共同编写:

这个错误是因为你的代码在调用fread函数时,stream参数为nullptr导致的断言失败。

在你的代码中,调用fread的地方是:

cpp
FILE* fp = fopen(mypath, "rb"); 
int len = fread(sendBuff, 1, 1000, fp);
fclose(fp);

然而,如果mypath为空字符串或错误路径,fopen函数将失败,fp将为nullptr。此时调用fread(fp)就会导致断言失败。

解决方案是:

  1. 在调用fopen前检查mypath是否为空或错误,避免fp为nullptr的情况出现。

  2. 在调用fread前也检查fp是否为nullptr,如果是则跳过fread调用。

修改后的代码可以是:

cpp
if (mypath[0] != '\0') {
    FILE* fp = fopen(mypath, "rb");
    if (fp != nullptr) {
        int len = fread(sendBuff, 1, 1000, fp);
        fclose(fp);
    }
}
或者
cpp
FILE* fp = fopen(mypath, "rb");
if (fp != nullptr) {
    int len = fread(sendBuff, 1, 1000, fp);
    fclose(fp); 
}

这样就可以避免在fp为nullptr的情况下调用fread导致的断言失败错误了。

希望这个解释和解决方案能帮助你解决Visual C++的断言失败错误。C/C++程序在调用各个API时都需要确保参数的有效性,否则容易导致意外的错误和崩溃。要养成检查参数的好习惯,在调用任何API前先判断参数是否满足要求,这可以极大提高程序的健壮性。

  • 你可以参考下这个问题的回答, 看看是否对你有帮助, 链接: https://ask.csdn.net/questions/7612851
  • 你也可以参考下这篇文章:模态对话框VS非模态对话框
  • 除此之外, 这篇博客: 格式化输入输出和按位运算中的 逻辑运算VS按位运算 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    • 对于逻辑运算,它只看到两个值:0和1
    • 可以认为逻辑运算相当于把所有非0值都变成1,然后做按位运算
    • 5&4——>4而  5&&4——>1&1——>1
    • ~4——>3而!4——>!1——>0
    • 逻辑结果只输出1或者0

    位段:

    • 把一个int 的若干位组合成一个结构
    struct{
        unsigned int leading: 3;//数字表示该类型占多少个比特
        unsigned int FLAG1: 1;
        unsigned int FLAG2: 1;
        int trailing: 11;
    };
    • 可以直接用位段的成员名称来访问
    • 比移位、与、或还方便
    • 编译器会安排其中的位的排列,不具有可移植性
    • 当所需的位超过一个int时会采用多个int
    #include<stdio.h>
    
    void prtBin(unsigned int number);
    
    struct U0{
    	unsigned int leading : 3;//unsgined即无符号化,取消负数,增大正数的范围 
    	unsigned int FLAG1 : 1;
    	unsigned int FLAG2 : 1;
    	int trailing : 27;
    }; 
    
    int main()
    {
    	struct U0 uu;
    	uu.leading=2;
    	uu.FLAG1=0;
    	uu.FLAG2=1;
    	uu.trailing=0;
    	printf("sizeof(uu)=%lu\n",sizeof(uu));
    	prtBin(*(int*)&uu);
    	
    	return 0;
    }
    
    void prtBin(unsigned int number)
    {
    	unsigned mask=1u<<31;//左移31位,右边补入0.即原为0变成0000000..00000 
    	for(;mask;mask>>=1){
    		printf("%d",number&mask?1:0);//若number&mask为真,则输出1,否则输出0 
    	}//&是按位与,同时为1则为1 
    	
    	printf("\n");
    }
    
    //结果: 
    //sizeof(uu)=4
    //00000000000000000000000000010010
    • U表示该常数用无符号整型方式存储,相当于 unsigned int
    • L表示该常数用长整型方式存储,相当于 long
    • F表示该常数用浮点方式存储,相当于 float
    • 1U则是代表该无符号整型的值为1,可以表示如下:
      00000000…1(最后一位为1)(31个0 1个1)
  • 以下回答由chatgpt基于相关博客总结生成:

    我很抱歉,根据您提供的参考资料以及问题描述,无法理解您遇到的具体问题是什么。请提供更具体的问题描述或者相关代码片段以便我可以更好地为您提供帮助。