我在 Visual Studio 預覽版中撰寫了一個 HTTP 服務器,并添加<meta charset="utf-8">了使用 UTF-8 作為內容編碼。
問題是當我在字串文字上使用u8 前綴時,瀏覽器看起來有編碼錯誤。
當我洗掉u8前綴時,瀏覽器會正確顯示??。
為什么?
我的檔案是用utf-8 保存的(代碼頁 65001)
帶u8前綴的字串

u8不帶前綴的字串

編輯
更新示例代碼
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define U8
#ifdef U8
typedef const char8_t c;
c str[] = u8"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\xf0\x9f\x93\x9d</h1>";
#else
typedef const char c;
c str[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\xf0\x9f\x93\x9d</h1>";
#endif
template <ULONG N>
constexpr ULONG cstrlen(c(&)[N]) {
return N - 1;
}
int main() {
WSADATA wsaData;
SOCKET listener, s;
CHAR buf[1024 * 3];
WSABUF wsabuf{ .len = sizeof(buf), .buf = buf };
DWORD bytes, flags = 0;
const char* err = "?";
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
err = "WSAStartup";
goto Err;
}
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* result;
if (getaddrinfo(NULL, "80", &hints, &result)) {
err = "getaddrinfo";
goto Err;
}
listener = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (listener == INVALID_SOCKET) {
freeaddrinfo(result);
err = "WSASocket";
goto Err;
}
if (bind(listener, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
err = "bind";
closesocket(listener);
goto Err;
}
freeaddrinfo(result);
if (listen(listener, SOMAXCONN) == SOCKET_ERROR) {
err = "listen";
closesocket(listener);
goto Err;
}
}
puts("Ready...");
for (;;) {
s = WSAAccept(listener, NULL, NULL, NULL, NULL);
if (s == INVALID_SOCKET) {
closesocket(listener);
err = "WSAAccept";
goto Err;
}
wsabuf.len = sizeof(buf);
wsabuf.buf = buf;
bytes = flags = 0;
if (WSARecv(s, &wsabuf, 1, &bytes, &flags, NULL, NULL) == SOCKET_ERROR) {
err = "WSARecv";
goto Err;
}
wsabuf.buf = (char*)str;
wsabuf.len = cstrlen(str);
if (WSASend(s, &wsabuf, 1, &bytes, 0, NULL, NULL)) {
err = "WSASend";
closesocket(s);
goto Err;
}
closesocket(s);
}
return 0;
Err:
puts(err);
WSACleanup();
return 1;
}
運行std=c 20
uj5u.com熱心網友回復:
感謝@AlanBirtles,使用\u文字解決我的問題。
u8沒有u8兩者都適用\U0001f4dd
更新代碼
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#pragma comment (lib, "ws2_32.lib")
#define U8
#ifdef U8
typedef const char8_t c;
c str[] = u8"HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\U0001f4dd</h1>";
#else
typedef const char c;
c str[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html; charset=utf-8\r\n\r\n<h1>\U0001f4dd</h1>";
#endif const char c;
template <ULONG N>
constexpr ULONG cstrlen(c(&)[N]) {
return N - 1;
}
int main() {
WSADATA wsaData;
SOCKET listener, s;
CHAR buf[1024 * 3];
WSABUF wsabuf{ .len = sizeof(buf), .buf = buf };
DWORD bytes, flags = 0;
const char* err = "?";
if (WSAStartup(MAKEWORD(2, 2), &wsaData)) {
err = "WSAStartup";
goto Err;
}
{
struct addrinfo hints = {};
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_flags = AI_PASSIVE;
struct addrinfo* result;
if (getaddrinfo(NULL, "80", &hints, &result)) {
err = "getaddrinfo";
goto Err;
}
listener = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_IP, NULL, 0, WSA_FLAG_OVERLAPPED | WSA_FLAG_NO_HANDLE_INHERIT);
if (listener == INVALID_SOCKET) {
freeaddrinfo(result);
err = "WSASocket";
goto Err;
}
if (bind(listener, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
freeaddrinfo(result);
err = "bind";
closesocket(listener);
goto Err;
}
freeaddrinfo(result);
if (listen(listener, SOMAXCONN) == SOCKET_ERROR) {
err = "listen";
closesocket(listener);
goto Err;
}
}
puts("Ready...");
for (;;) {
s = WSAAccept(listener, NULL, NULL, NULL, NULL);
if (s == INVALID_SOCKET) {
closesocket(listener);
err = "WSAAccept";
goto Err;
}
wsabuf.len = sizeof(buf);
wsabuf.buf = buf;
bytes = flags = 0;
if (WSARecv(s, &wsabuf, 1, &bytes, &flags, NULL, NULL) == SOCKET_ERROR) {
err = "WSARecv";
goto Err;
}
wsabuf.buf = (char*)str;
wsabuf.len = cstrlen(str);
if (WSASend(s, &wsabuf, 1, &bytes, 0, NULL, NULL)) {
err = "WSASend";
closesocket(s);
goto Err;
}
closesocket(s);
}
return 0;
Err:
puts(err);
WSACleanup();
return 1;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/475879.html
上一篇:c#在設計時檢查值
