我是C ++上的字符串的新手,我已经有几个小时了,我已经在很多论坛上了,所以我理解什么样的char *是LPSTR,LPCSTR或LPCSTR,但我找不到方式并了解如何使用它们构建字符串。
我打算使用GetCurrentDirectoryA和CopyFileA复制/粘贴新文件。
这是我的代码:
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <windows.h>
#include <winbase.h>
using namespace std;
#define DR drum-
#define NO normal-
#define SO soft-
//main
int main(){
LPCTSTR input;
LPCTSTR output;
LPSTR cd;
LPCSTR src = "source.wav";
if(GetCurrentDirectoryA(strlen(cd), cd)){
input = (LPCTSTR)cd + (LPCTSTR)src;
if(CopyFileA(input, cd + "DR" + "hitclap.wav"))
cout<<"done"<<endl;
else
cout<<"error"<<endl;
}
}
答案 0 :(得分:2)
API private void ChangeToDoubleWhenLeave(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox != null)
{
double value;
if (double.TryParse(textBox.Text, out value))
{
textBox.Text = value.ToString("F");
}
}
}
不会向您返回新字符串。它的作用是将它传递给一个内存位置,并使用当前目录字符串填充该内存位置。
问题是你没有分配内存,你传递了未初始化的GetCurrentDirectory
(char*
),LPSTR
。您还在此未初始化的字符指针上使用cd
。通常,您使用长度为strlen
的字符数组来播放文件名:
MAX_PATH
第二个注意事项是您不能使用char cd[MAX_PATH];
GetCurrentDirectoryA(sizeof(cd), cd);
运算符来连接C字符串。要么你去C路线并使用+
[1]和朋友,要么你去C ++路线并用strcat
替换你所有的char*
并使用它。
选择其中一条道路,然后阅读std::string
上的教程 - C中的字符串或C ++中的char*
。
要正确理解std::string
类型及其与LPTSTR
的关系,请参阅我创建的this question & answer。
答案 1 :(得分:1)
DWORD WINAPI GetCurrentDirectory(
_In_ DWORD nBufferLength,
_Out_ LPTSTR lpBuffer
);
lpBuffer
是指向内存缓冲区的指针,其中应放置内容,nBufferLength是TCHAR中此内存区域的大小。
所以正确的代码是:
TCHAR szBuffer[MAX_PATH];
GetCurrentDirectory(MAX_PATH, szBuffer);
你必须使用TCHAR作为非unicode构建它将解析为char,而对于unicode它将是wchar_t。
答案 2 :(得分:1)
欢迎使用80286内存模型的遗留问题以及Windows操作系统使用的8位字符到(某种)unicode的演变。
LPCSTR表示:&#34;指向const字符串的长指针&#34;今天相当于const char*
。不是很多年前它等同于const char* far
- 远远是微软的扩展,告诉编译器地址可能在不同的内存段(如果你真的在乎,谷歌是你的朋友&#34;分段内存型号80286&#34;)
LPCTSTR表示:指向const的长指针[宽或8位,取决于编译器标志]字符。例如之一:
const char*
或const wchar_t*
取决于构建模式。
同样LPSTR今天char *
,但曾经只有char * far
。
所以你可以看到Windows API实际上是使用原始指针到c样式的字符串,这些字符串是const或mutable,以及宽字符或8位字符,具体取决于上下文和构建选项。
答案 3 :(得分:1)
使用BoostFilesystem¹你会写:
<强> Live On Coliru 强>
#include <boost/filesystem.hpp>
#include <iostream>
#define dr "drum -"
#define no "normal -"
#define so "soft -"
int main() {
using boost::filesystem::path;
auto input = absolute(path("source.wav"));
auto output = absolute(path(dr "hitclap.wav"));
std::cout << input << " " << output << "\n";
}
打印
"/tmp/1448053072-1243850518/source.wav" "/tmp/1448053072-1243850518/drum -hitclap.wav"
你可以从那里拿走它。
¹注意:Microsoft Visual C ++发布了
<filesystem>
的版本,因为...... VS2010甚至我认为。所以你可能根本不需要提升来享受郁郁葱葱的生活:)
答案 4 :(得分:0)
每当我使用需要或使用LPSTR / LPCTSTR的东西时,我倾向于使用std :: wstring代替:
std::wstring input = _T("");
input.append(_T("Sample Text"));
input.append(std::to_wstring(myint));
std::copy(mystring.begin(), mystring.end(), text.end());
这使得可以使用字符串代替LPCTSTR。我不知道它是否适用于这种情况,但我认为它会。
编辑:正如@MicroVirus所说,你应该一路走下去并且使用TCHAR来做所有事情,这样你的程序就兼容ANSI和Unicode(你的函数使用ANSI,如尾随&#39; A& #39;)答案 5 :(得分:0)
您可以使用以下命令将<string>
STL库与Windows W API一起使用:
#include <cassert>
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
#include <windows.h>
using std::endl;
using std::cout;
using std::cerr;
using tstring = std::basic_string<TCHAR>;
const std::wstring dr = L"drum-";
// OR: const tstring dr = TEXT("drum-");
const std::wstring no = L"normal-";
const std::wstring so = L"soft-";
const std::wstring src = L"drum.wav";
const std::wstring dest = L"hitclap.wav";
int main()
{
const std::vector<wchar_t>::size_type cd_buf_len = GetCurrentDirectoryW( 0, NULL );
assert( cd_buf_len > 0 );
std::vector<wchar_t> cwd( cd_buf_len, 0 );
const DWORD cd_result = GetCurrentDirectoryW( cd_buf_len, cwd.data() );
assert(cd_result);
if (CopyFileW( (cwd.data() + src).c_str(), (cwd.data() + dr + dest).c_str(), FALSE )) {
cout << "Done." << endl;
} else {
cerr << "Error." << endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
此版本已修复以更正初始帖子中的错误:修改.c_str()
会导致未定义的行为。它在概念上很简单并且按要求使用添加,但是不如分配缓冲区并将源字符串复制到它们或使用+=
那样高效。因此,您可能真的想写:
constexpr wchar_t src[] = L"drum.wav";
/* … */
std::wstring src_path = cwd.data();
src_path += src;
要使用TCHAR
版本,请将wchar_t
更改为TCHAR
,将L"foo"
更改为TEXT("foo")
,将std::wstring
更改为tstring
},将LPWSTR
更改为LPTSTR
,将GetCurrentDirectoryW
更改为GetCurrentDirectory
等。
通常,您不希望在同一程序中混合使用8位和宽字符串,除非您明确需要在一个编码中输入并在另一个编码中输出。如果是这样,您必须显式转换,例如将当前代码页设置为65001(UTF-8)并使用std::wstring_convert
。