3

我正在使用Linux。

我有一个函数叫做:

PlayBackgroundIntroMusic((char *)"IntroMusic");

功能是:

无效的声音管理器::
PlayBackgroundIntroMusic(char * musicFile)
{
        // 为每个平台连接扩展
        strcat(音乐文件,音频扩展);
        CCLOG("musicFile: %c" musicFile);
  SimpleAudioEngine::sharedEngine()->playBackgroundMusic(std::string(CCFileUtils::fullPathFromRelativePath(musicFile)).c_str(), false);
}

但是我无法在线访问内存:

strcat(音乐文件,音频扩展);

声明了 audioExtension:

#包括
使用标准::字符串;
#包括
使用 std::cout;使用 std::cerr;使用 std::endl;

/**
 * 为每个平台声明声音扩展
 * 安卓 = ogg
 * iOS = 咖啡馆
 * WIN32 = mp3
 */

#if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
        静态 const char * audioExtension = ".wav";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
        静态 const char * audioExtension = ".caf";
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        静态 const char * audioExtension = ".ogg";
#万一

所以,我希望有:

iOS 上的 IntroMusic.caf
Android 上的 IntroMusic.ogg

发生了什么事?

注意:我试图:

char * musicFileWithExtension = strcat (musicFile,audioExtension);

但它无论如何都没有用。

musicFile 不是一个常数。如果文件名太长,我不想声明 tempchar[80] 以避免溢出,例如示例 cc 参考

提前致谢。

4

3 回答 3

5

字符串文字,例如"IntroMusic"可以const char[N]隐式转换为const char *. 由于语言设计中的错误,它也可以转换为char*,但这种转换在 C++ 中被正确弃用,因此发出警告。您需要使用数组(动态或静态分配),而不是字符串文字。

或者更好的是,使用std::string.

于 2012-06-22T07:17:53.053 回答
2

首先,“IntroMusic”是常量。

从 const 值中删除 const-ness 并对其进行修改是未定义的行为。任何事情都可能发生,你很幸运能立即得到崩溃。

此外,为“IntroMusic”分配的内存正好是字符的 10 个字节加上一个定界符\0,所以总共 11 个字节。时期。现在,除了你试图强制修改一个const值之外,你甚至写入未分配的内存(至少,不是你为了写入而分配的):你只需尝试将依赖于平台的文件扩展名写入内存在“介绍音乐”之后。

您有责任为您的操作提供足够大的缓冲区。

简单的解决方案(因为您标记了问题c++,而不是c:使用std::string

于 2012-06-22T07:20:15.537 回答
1

查看 strcat 文档。它正在将目标字符串添加到源字符串。在您的情况下,源字符串是“musicFile”,因此它不应该是恒定的并且应该有足够的长度。

如果函数是这样调用的:

PlayBackgroundIntroMusic((char *)"IntroMusic");

那么 musicFile == "IntroMusic" 是常量,不能被覆盖。

于 2012-06-22T07:18:04.530 回答