Questions in category: C++ (C++)
软件 >> C++ [35]
<[1] [2] [3] [4] >

1. error C2011: “sockaddr”:“struct”类型重定义

Posted by haifeng on 2025-11-09 20:59:36 last update 2025-11-09 22:18:27 | Answers (0) | 收藏


error C2011: “sockaddr”:“struct”类型重定义

这个问题的出现主要伴随着包含 Windows.h 的文件. 打开 Windows.h 这个文件. 有这样一段.


#ifndef WIN32_LEAN_AND_MEAN
#include <cderr.h>
#include <dde.h>
#include <ddeml.h>
#include <dlgs.h>
#ifndef _MAC
#include <lzexpand.h>
#include <mmsystem.h>
#include <nb30.h>
#include <rpc.h>
#endif
#include <shellapi.h>
#ifndef _MAC
#include <winperf.h>
#include <winsock.h>
#endif
#ifndef NOCRYPT
#include <wincrypt.h>
#include <winefs.h>
#include <winscard.h>
#endif

#ifndef NOGDI
#ifndef _MAC
#include <winspool.h>
#ifdef INC_OLE1
#include <ole.h>
#else
#include <ole2.h>
#endif /* !INC_OLE1 */
#endif /* !MAC */
#include <commdlg.h>
#endif /* !NOGDI */
#endif /* WIN32_LEAN_AND_MEAN */


我们看到如果没有定义 WIN32_LEAN_AND_MEAN, 且也没有定义 _MAC, 则会加载 winsock.h

而 winsock.h 中有 sockaddr 结构的定义:

/*
 * Structure used by kernel to store most
 * addresses.
 */
struct sockaddr {
        u_short sa_family;              /* address family */
        char    sa_data[14];            /* up to 14 bytes of direct address */
};


而 ws2def.h 中也有 sockaddr 结构的定义

//
// Structure used to store most addresses.
//
typedef struct sockaddr {

#if (_WIN32_WINNT < 0x0600)
    u_short sa_family;
#else
    ADDRESS_FAMILY sa_family;           // Address family.
#endif //(_WIN32_WINNT < 0x0600)

    CHAR sa_data[14];                   // Up to 14 bytes of direct address.
} SOCKADDR, *PSOCKADDR, FAR *LPSOCKADDR;


WinSock2.h 在必要情况下会包含进 Windows.h

/*
 * Pull in WINDOWS.H if necessary
 */
#ifndef _INC_WINDOWS
#include <windows.h>
#endif /* _INC_WINDOWS */

此外它引入了 ws2def.h, 

#include <ws2def.h>

 

因此, 解决冲突的办法是仅使用其中一种定义. 一般现在不使用 winsock.h. 故在项目中凡是 #include <Windows.h> 的地方, 在前面加上 #define WIN32_LEAN_AND_MEAN

 


注: 以我的电脑为例,

Windows.h 所在文件夹一般为 C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um

ws2def.h 所在文件夹为 C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\shared

winsock.h 和 WinSock2.h 均位于C:\Program Files (x86)\Windows Kits\10\Include\10.0.26100.0\um

 

2. C++ 无法重载仅按返回类型区分的函数.

Posted by haifeng on 2024-06-27 17:57:08 last update 2024-06-27 17:57:08 | Answers (0) | 收藏


如果有两个函数, 函数名和参数列表相同, 仅返回类型不同, 这是不能区分的.  E0311

poly_node* new_poly_from_string_Multi(const char* str);

expr_node* new_poly_from_string_Multi(const char* str);

 

3. [C++] find_last_of

Posted by haifeng on 2024-04-08 09:58:20 last update 2024-04-08 10:03:20 | Answers (0) | 收藏


C++ 中的 find_last_of() 函数经常会被误认为在字符串中搜寻某个字串最后出现的位置. 实际上它的功能是在字符串中搜索与其参数中指定的任何字符匹配的最后一个字符.

find_last_of() 有以下多种声明.

string (1)
size_t find_last_of (const string& str, size_t pos = npos) const;
c-string (2)
size_t find_last_of (const char* s, size_t pos = npos) const;
buffer (3)
size_t find_last_of (const char* s, size_t pos, size_t n) const;
character (4)
size_t find_last_of (char c, size_t pos = npos) const;

 

现在输入 symbol(x y what),  希望从末尾开始搜寻`)`, 则建议使用 

size_t rfind (char c, size_t pos = npos) const;

rfind() 会从指定的 pos 参数开始在字符串中往前寻找第一次出现的字符c.

 

参考

cplusplus.com/reference/string/string/find_last_of/

4. 整型变量未定义时, 在 Debug 时显示的值

Posted by haifeng on 2023-08-29 07:56:42 last update 2023-08-29 07:56:42 | Answers (0) | 收藏


当一个整型变量未定义时, 在 Debug 时显示的值为 -858993460 

5. C 语言中打开文件的代码

Posted by haifeng on 2023-03-05 11:27:43 last update 2023-03-05 11:42:17 | Answers (0) | 收藏


 

FILE* inputFile;

const char * file_in;

if ((inputFile = fopen(file_in, "r")) == NULL)     //读取输入文件
{
printf("\nerror: 无法打开输入文件: %s\n\n", file_in);
std::cerr << "Parser: could not open input file '" << file_in << "'!\n";
return EXIT_FAILURE;
}

 

但若在 Visual Studio 下, 会提示 fopen 不安全, 建议使用 fopen_s.

//Declaring a variable of type errno_t to store the return value of fopen_s
    errno_t error_code1; 
    //Opening file in r mode
    error_code1 = fopen_s(&inputFile, file_in, "r");
    if (error_code1 != 0) {
        printf("Error! Failed to open file %s in r mode!", file_in);
    }

7. 检测输入的参数 str 是否是有效的二进制表达式

Posted by haifeng on 2023-02-14 10:49:44 last update 2023-02-14 10:49:44 | Answers (0) | 收藏


//检测 str 是否只包含数字0或1, 也就是检测是否是二进制数
//11010010 

bool BigNumber::isBinaryNumber(const string &str)
{
    return find_if(str.begin(), str.end(),
        [](char c) { 
          return !((c=='0') || (c=='1')) ;
        }) == str.end();
}

 

修改上面的程序, 使满足下面的要求

1111011.01110100101111 也是有效的二进制数. 注意小数点最多只能一个.

8. 整数到字符串的转换

Posted by haifeng on 2022-06-25 12:06:58 last update 2022-06-25 12:53:00 | Answers (0) | 收藏


在非标准 C 库中有一个函数 itoa, 可以将各种进制的整数转换为C风格的字符串.

函数原型为

char *  itoa ( int value, char * str, int base );

 

字符串转为长整型

long int atol ( const char * str );

 

9. 程序设计竞赛网站

Posted by haifeng on 2022-03-30 11:40:45 last update 2022-03-30 11:40:45 | Answers (0) | 收藏


洛谷

https://www.luogu.com.cn/

 

蓝桥杯

https://dasai.lanqiao.cn/

 

ACM/ICPC 信息站
http://acmicpc.info

中国大学生程序设计竞赛
China Collegiate Programming Contest
https://ccpc.io/

10. Compiler Explorer

Posted by haifeng on 2022-03-09 12:31:49 last update 2022-03-09 12:31:49 | Answers (0) | 收藏


Compiler Explorer (godbolt.org)

https://godbolt.org/

 

C++  -->  汇编

<[1] [2] [3] [4] >