Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
String 需要将字符串^转换为字符*_String_C++ Cli_Char - Fatal编程技术网

String 需要将字符串^转换为字符*

String 需要将字符串^转换为字符*,string,c++-cli,char,String,C++ Cli,Char,我正在使用.NET日期时间获取当前日期和时间。我正在将其转换为字符串以用作文件名的一部分。问题是保存图像的OpenCV命令需要char*而不是字符串类型,DateTime将只输出字符串^type。我该怎么做?这是未完成的代码 String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm"); IplImage* toSave; CvCapture* capture = cvCreateCameraCapt

我正在使用.NET日期时间获取当前日期和时间。我正在将其转换为字符串以用作文件名的一部分。问题是保存图像的OpenCV命令需要char*而不是字符串类型,DateTime将只输出字符串^type。我该怎么做?这是未完成的代码

String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
        IplImage* toSave;
        CvCapture* capture = cvCreateCameraCapture(0);
        toSave = cvQueryFrame( capture );
        cvSaveImage(nowString, toSave);
        cvReleaseImage(&toSave);
        cvReleaseCapture(&capture);

您需要阅读C++互操作和数据编组。

基本上:需要将.NET代码>字符串强制转换为C++ <代码> TCHAR< <代码>数组.< /P>


看到这个:

随机谷歌搜索得到了这个。也许有人可以缩短它

cli::array<char>^ bytes = Encoding::ASCII::GetBytes(nowString);
pin_ptr<char> pinned = &bytes[0];
std::string nativeString((char*)pinned, bytes->Length);
char const* chars = nativeString.c_str();
cli::array^bytes=Encoding::ASCII::GetBytes(nowString);
pin_ptr pinted=&字节[0];
std::string nativeString((char*)固定,字节->长度);
char const*chars=nativeString.c_str();

编辑:这比封送处理类的操作长,但可以使用更多的编码。在您的情况下,听起来更简单的
StringToHGlobalAnsi
方法可以满足您的所有需要。

使用中的
stringtoxxansi
函数分配
char*
缓冲区,然后从同一类中释放相应的函数。

您最好的选择是使用
StringToHGlobalAnsi
。下面是完整的代码,显示了它是如何完成的,并记住释放分配的内存

using namespace System::Runtime::InteropServices;

void MethodName()
{
    String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
    IntPtr ptrToNativeString = Marshal::StringToHGlobalAnsi(nowString);
    try
    {
        CvCapture* capture = cvCreateCameraCapture(0);
        IplImage* toSave = cvQueryFrame(capture);
        cvSaveImage(static_cast<char*>(ptrToNativeString.ToPointer()), toSave);
        cvReleaseImage(&toSave);
        cvReleaseCapture(&capture);
    }
    catch (...)
    {
        Marshal::FreeHGlobal(ptrToNativeString);
        throw;
    }
    Marshal::FreeHGlobal(ptrToNativeString);
}
使用命名空间System::Runtime::InteropServices;
void MethodName()
{
字符串^nowString=DateTime::Now.ToString(“yyyy-MM-dd-HH:MM”);
IntPtr ptrToNativeString=Marshal::StringToHGlobalAnsi(nowString);
尝试
{
CvCapture*capture=cvCreateCameraCapture(0);
IplImage*toSave=cvQueryFrame(捕获);
cvSaveImage(static_cast(ptrToNativeString.ToPointer()),toSave);
cvReleaseImage(&toSave);
cvReleaseCapture(&capture);
}
捕获(…)
{
元帅:FreeHGlobal(ptrToNativeString);
投掷;
}
元帅:FreeHGlobal(ptrToNativeString);
}

您可能需要重新考虑在文件名中使用“:”字符,因为我认为windows不太喜欢这样。

事实上,我发现从
字符串中获取
字符*
的最简单方法是使用好的ol'
sprintf()
。因此,在您的情况下,您可以简单地执行以下操作:

char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
if (nowString->Length < sizeof(cNow)) // make sure it fits & allow space for null terminator
  sprintf(cNow, "%s", nowString);
那么这应该是可行的:

char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
string sNow = marshal_as<string>(nowString);
if (sNow.length() < sizeof(cNow)) // make sure it fits & allow space for null terminator
  sprintf(cNow, "%s", sNow.c_str());

为什么要全套帽子?你在喊吗?大概他的帽子锁卡住了。这也解释了为什么他拼写“.net”时没有大写字母。错误地击中大写字母锁“错误地”?我猜你错误地点击了提交,错误地忘记了在提交之前阅读。你不需要解释或道歉。把它修好。许多人做了更糟糕的事情。@S.Lott你不会因为做了一个蠢驴而改正它。使用Marshal::FreeHGlobal()而不是Marshal::FreeCoTaskMem()更合适吗?我对StringToHGlobalAnsi()的MSDN帮助说,使用FreeHGlobal()释放内存;编辑制作。我想我已经养成了默认使用FreeCoTaskMem的习惯。与其在这里编写两次释放指针的代码,您最终可以使用<代码>尝试{…}最后{Marshal::FreeHGlobal(…)}
我对此表示怀疑-没有什么比这更容易的了-但它似乎确实有效(使用Visual Studio 2012)。有没有什么不好的事情发生在幕后,这意味着我们不应该只做这件事?@njplumridge当我了解到这项技术时,我也很怀疑。我猜这是在幕后进行编组,但其他人可能知道得更多。但这隐藏了所有的复杂性。在sprintf()防止缓冲区溢出之前,我会检查大小。请参阅上面我的编辑。@n它正在幕后进行编组。有关详细信息,请参阅。哈,我正要添加一个指向该答案的链接-你比我快了:-)遗憾的是,在VS2015下,它失败了
'sprintf':格式字符串“%s”需要类型为“char*”的参数,但变量参数1的类型为“System::string^”
char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
string sNow = marshal_as<string>(nowString);
if (sNow.length() < sizeof(cNow)) // make sure it fits & allow space for null terminator
  sprintf(cNow, "%s", sNow.c_str());
char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
if (nowString->Length < sizeof(cNow)) // make sure it fits & allow space for null terminator
{
    for (int i = 0; i < nowString->Length; i++)
        cNow[i] = static_cast<char>(nowString[i]);
}