gpt4 book ai didi

c++ - 在编译时更改字符串宏

转载 作者:太空狗 更新时间:2023-10-29 20:39:54 26 4
gpt4 key购买 nike

我正在开发一个必须在不同机器上工作的独特客户端。在每台机器上,服务器都在不同的 IP 地址中运行,但这个地址是已知的。

我不想在每次运行时都告诉客户端哪个是IP,所以我想在编译时告诉它。

问题是,当使用 g++ -DHOSTNAME=127.0.0.1(也尝试使用双引号)编译时,编译器说:

error: too many decimal points in number
./include/Client.h:18:25: note: in expansion of macro ‘HOSTNAME’

我也尝试使用本地主机。

error: ‘localhost’ was not declared in this scope
./include/Client.h:18:25: note: in expansion of macro ‘HOSTNAME’

还尝试使用在互联网上找到的一些东西。

#define XSTR(x) STR(x)
#define STR(x)

编译错误:

./src/BSCClient.cpp:15:45: note: #pragma message: HOSTNAME: 
#pragma message("HOSTNAME: " XSTR(HOSTNAME))

./src/BSCClient.cpp:16:39: error: too few arguments to function ‘hostent* gethostbyname(const char*)’
server = gethostbyname(XSTR(HOSTNAME));

在这一点上,我在想也许宏不是处理这个问题的正确方法,但我不知道该怎么做。

如果有人对此有任何引用,我将不胜感激。

编辑:这些是代码。

客户端.h:

#ifndef __CLIENT_HH__
#define __CLIENT_HH__

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>

#include <string>
#include <iostream>

using namespace std;

#define HOSTNAME 127.0.0.1
#define MAX_MESSAGE_LENGTH 10

class Client {
private:
string client_name;
int sockfd, portno;
struct sockaddr_in serv_addr;
struct hostent *server;
error(const char *msg);

public:

BSCClient (string name, int port);
void identifyme();
void sendData (string data);
string recvData ();

void closeSocket();
};

#endif

客户端.cpp

#include "BSCClient.h"

#include <stdlib.h>
#include <time.h>

void BSCClient::error(const char *msg)
{
perror(msg);
exit(0);
}

Client::Client(string name, int port)
{
sockfd = socket(AF_INET, SOCK_STREAM, 0);
portno = port;
client_name = name;

if (sockfd < 0)
error("ERROR opening socket");

server = gethostbyname(HOSTNAME);

if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}

bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR connecting");

sendData(client_name);
}

void Client::identifyme() {
FILE *fp;
fp = popen("id -gn", "r");

char text[6];
fscanf(fp, "%s", text);
pclose(fp);
string data(text);
sendData(data);
}

void Client::sendData (string data) {
const char *sdata = data.c_str();
int n;
n = write(sockfd, sdata, strlen(sdata));
if (n < 0)
error("ERROR writing to socket");
}

string Client::recvData () {
int n;
int bytes;
char *longitud = new char[MAX_MESSAGE_LENGTH+1];
n = read(sockfd, longitud, MAX_MESSAGE_LENGTH);
if (n < 0) {
error("ERROR recieving size of output");
}
bytes=atoi(longitud);
//Para forzar el fin del string (ya que al imprimir el string hay veces que muestra caracteres de más)
longitud[MAX_MESSAGE_LENGTH]='\0';
char *data = new char[bytes];
n = read(sockfd, data, bytes);
if (n < 0)
error("ERROR reading output");
string ret(data);
return ret;
}

void Client::closeSocket() {
close(sockfd);
}

最佳答案

你必须转义双引号:

g++ -DHOSTNAME=\"127.0.0.1\"

否则,引号只是告诉您的 shell 127.0.0.1 是您要赋予 -DHOSTNAME 的值,它如果该值包含空格,则可能很有用,例如:

g++ -DMAGIC_NUMBER="150 / 5"

(那里,MAGIC_NUMBER 将替换为 150/5,不带引号)

如果您希望引号成为宏的一部分(如 #define HOSTNAME "127.0.0.1"),您必须告诉您的 shell 它们是您提供的值的一部分到 -DHOSTNAME,这是通过转义它们来完成的。

编辑:

此外,正如 Angew 所指出的,您误用了 XSTR 技巧。与我的答案不同,这是解决您问题的另一种方法。

它当然是这样工作的:

#define XSTR(x) STR(x)
#define STR(x) #x

有了它,您就不必转义引号了。

这两个宏将文本 127.0.0.1 更改为 "127.0.0.1"XSTR 宏允许 HOSTNAMESTR 宏将其转换为 之前扩展为 127.0.0.1 “127.0.0.1”。如果您直接使用 STR 宏,您最终会得到 "HOSTNAME" 而不是 "127.0.0.1"

我想我更喜欢转义解决方案,而不是在代码中使用涉及两个宏的技巧,但这也行得通。

关于c++ - 在编译时更改字符串宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26213071/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com