C ++:定义简单常量使用?

时间:2010-05-08 12:41:19

标签: c++ string constants

在C ++中我想定义一个我可以在另一个函数中使用的常量,关于如何做到这一点的简短答案会很好..

让我们说在我的代码开头我想定义这个常量:

//After #includes
bool OS = 1; //1 = linux
if (OS) {
  const ??? = "clear";
} else {
  const ??? = "cls";
}

我不知道用什么类型来定义“清除”字符串...我很困惑。

后来我想在一个函数中使用它:

int foo() {
 system(::cls); //:: for global

 return 0;
}

如何在顶部定义字符串,并在下面使用字符串?我听说char只有一个字符和东西......我不确定如何使用,因为它说它将字符串转换为const char或其他东西。

4 个答案:

答案 0 :(得分:4)

char*不是charchar*基本上是一个字符串(它是C ++出现之前的字符串)。

例如:

int array[N];  // An array of N ints.
char str[N];   // An array of N chars, which is also (loosely) called a string.

char[]降级为char*,因此您经常会看到函数占用char*

要将std::string转换为const char*,您只需致电:

std::string s;
s.c_str()

在这种情况下,通常使用预处理器来定义您的操作系统。这样您就可以使用编译器来执行特定于平台的工作:

#ifdef OS_LINUX
const char cls[] = "clear";
#elif OS_WIN
const char cls[] = "cls";
#endif

您可能想要考虑的一件事就是让它成为一种功能。这避免了global construction order的讨厌依赖。

string GetClearCommand() {
  if (OS == "LINUX") {
    return "clear";
  } else if (OS == "WIN") {
    return "cls";
  }
  FAIL("No OS specified?");
  return "";
}

你想要做的是:

#include <iostream>
using namespace std;

#ifdef LINUX
const char cls[] = "LINUX_CLEAR";
#elif WIN
const char cls[] = "WIN_CLEAR";
#else
const char cls[] = "OTHER_CLEAR";
#endif

void fake_system(const char* arg) {
  std::cout << "fake_system: " << arg << std::endl;
}

int main(int argc, char** argv) {
  fake_system(cls);
  return 0;
}

// Then build the program passing your OS parameter.
$ g++ -DLINUX clear.cc -o clear
$ ./clear 
fake_system: LINUX_CLEAR

答案 1 :(得分:2)

这就是问题所在,你因为变量而超出了范围。如果我在括号内声明某些内容,它只存在于括号内。

if( foo ){
    const char* blah = "blah";
}

一旦我们离开if语句,变量blah就会消失。您需要将其本地实例化为您编写的任何括号。因此:

void Bar(){
    const char* blah = "blah";
    if( foo ){
        //blah exists within here
    }
}

但是,blah不会存在于Bar之外。得到它?

答案 2 :(得分:0)

另一个选择是使用一堆静态方法创建一个类。为每个命令创建一个新方法。类似的东西:

// in sys-commands.h
class SystemCommands {
public:
    static char const* clear();
    static char const* remove();
};

这为您提供了一些很好的实施选项。最好的方法是为编译期间选择的每个平台提供单独的实现文件。

// in sys-commands-win32.cpp
#include "sys-commands.h"
char const* SystemCommands::clear() { return "cls"; }
char const* SystemCommands::remove() { return "erase /f/q"; }

// in sys-commands-macosx.cpp
#include "sys-commands.h"
char const* SystemCommands::clear() { return "/usr/bin/clear"; }
char const* SystemCommands::remove() { return "/bin/rm -fr"; }

编译哪个文件将决定使用哪个命令集。您的应用程序代码如下所示:

#include <cstdlib>
#include "sys-commands.h"

int main() {
    std::system(SystemCommands::clear());
    return 0;
}

编辑:由于一系列原因,我忘了提到我更喜欢静态函数到全局常量。如果没有别的,您可以使它们非常量而不更改其类型 - 换句话说,如果您必须根据运行时设置选择命令集,则用户代码不必更改或甚至意识到发生了这样的变化。

答案 3 :(得分:0)

您可以使用公共头文件并根据系统链接到不同的模块:

// systemconstants.hpp

#ifndef SYSTEM_CONSTANTS_HPP_INCLUDED
#define SYSTEM_CONSTANTS_HPP_INCLUDED

namespace constants {
   extern const char cls[];  // declaration of cls with incomplete type
}

#endif

如果是Linux,只需编译并链接到这个:

// linux/systemconstants.cpp

#include "systemconstants.hpp"

namespace constants {
   extern const char cls[] = "clear";
}

如果是Windows,只需编译并链接到这个:

// windows/systemconstants.cpp

#include "systemconstants.hpp"

namespace constants {
   extern const char cls[] = "cls";
}

系统特定的翻译单元可以放在特定的子目录(linux / ,windows / 等)中,其中一个可以在构建过程中自动选择。这扩展到许多其他事情,而不仅仅是字符串常量。