我正在尝试在包含非拉丁字符的 Qt/C++ 软件上加载文件。 一个使用俄语文件名的用户报告的问题,我试图用下面的代码快速修复它。
示例文件名是(我不会读或写俄语!):Летний сад.dgr
bool QDepthmapView::loadFile(const QString &fileName)
{
m_open_file_name = fileName;
m_redraw_all = 1;
// this fixes the problem on a MacOSX but NOT on Windows!
QByteArray ba = fileName.toUtf8();
char *file = ba.data();
// end of fix
if(pDoc->OnOpenDocument(file)) // quick fix for weird chars (russian filename bug report)
{
// removed
}
return false;
}
上面的修复是我在网上找到的一个快速的肮脏的东西,它适用于我的 MacOSX10.8,但似乎 Windows 处理非 ASCII 字符有点不同,我不熟悉它。
我正在寻找用于加载非 ASCII 文件名的多平台解决方案(该软件可在 Win、Mac 和 Linux 上运行)。
编辑以下评论:
OnOpenDocument 转到:
int QGraphDoc::OnOpenDocument(char* lpszPathName)
{
m_opened_name = QString(lpszPathName);
int ok = m_meta_graph->read( lpszPathName );
// removed //
}
####
int read( const pstring& filename )
{
// cleared
#ifdef _WIN32
ifstream stream( filename.c_str(), ios::binary | ios::in );
#else
ifstream stream( filename.c_str(), ios::in );
#endif
//cleared
stream.read( (char *) &version, sizeof( version ) );
// cleared
}
####
template <class T>
istream& pmemvec<T>::read( istream& stream, streampos offset )
{
if (offset != streampos(-1)) {
stream.seekg( offset );
}
// READ / WRITE USES 32-bit LENGTHS (number of elements)
// n.b., do not change this to size_t as it will cause 32-bit to 64-bit conversion problems
unsigned int length;
stream.read( (char *) &length, sizeof(unsigned int) );
m_length = size_t(length);
if (m_length >= storage_size()) {
if (m_data) {
delete [] m_data;
m_data = NULL;
}
while (m_length >= storage_size())
m_shift++;
m_data = new T [storage_size()];
if (!m_data)
throw pexception( pexception::MEMORY_ALLOCATION, sizeof(T) * storage_size() );
}
if (m_length != 0) {
stream.read( (char *) m_data, sizeof(T) * streamsize(m_length) );
}
return stream;
}
最佳答案
欢迎来到 Windows 本地编码的精彩世界。
Windows 在内部以 UTF-16 工作(如 QString 所做的那样),但它的“遗留”narrow-char API 使用“本地代码页”,通常与系统代码页相同(虽然它可以在每个线程的基础上进行自定义 - 但是不能,它不能设置为 UTF-8,因为 Windows 10 1903 现在可以了!)。
这意味着大多数使用 char 的函数将它们直接传递给 Windows API(通常发生在 C/C++ 文件设施中)期望使用当前代码页编码的字符串。
QString 确实支持 toLocal8Bit 方法以在当前系统编码中提供其内容的 narrow-char 表示,这应该是 Windows 上的本地 CP 和 UTF- 8 在任何配置合理的 UNIX 上。
问题是,QString 到 UTF-8 是无损转换,因为它们都可以表示所有 Unicode 代码点; QString 与本地代码页的关系不大 - 例如,俄语字符不能在通常的 Windows-1252 CP 中编码。
出于这个原因,使用toLocal8Bit,您可以为流指定一个采用它期望的编码的文件名,但是您将无法打开包含当前代码页中未包含的字符的文件。
长话短说:通常避免任何问题的方法是始终将路径保持为 QString 并使用 QFile 打开文件。 QFile 通过使用 UTF-16 字符串调用 Windows API 的“widechar”版本并在 UNIX 系统上适本地转换为 UTF-8 来在内部处理这种错误。
如果您确实需要使用其他文件处理函数,您有两种选择:要么使用 toLocal8Bit 并放弃在 Windows 上处理具有“非本地”名称的文件,要么提供一个单独的代码适用于 wchar_t 的 Windows 路径(一直到 C 库和 Windows API 函数的宽字符版本)。
关于c++ - 俄语(或非拉丁语)文件名加载 Qt Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23888263/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende
我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("
我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co
我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
我对如何计算通过{%assignvar=0%}赋值的变量加一完全感到困惑。这应该是最简单的任务。到目前为止,这是我尝试过的:{%assignamount=0%}{%forvariantinproduct.variants%}{%assignamount=amount+1%}{%endfor%}Amount:{{amount}}结果总是0。也许我忽略了一些明显的东西。也许有更好的方法。我想要存档的只是获取运行的迭代次数。 最佳答案 因为{{incrementamount}}将输出您的变量值并且不会影响{%assign%}定义的变量,我
我有一个数组数组,想将元素附加到子数组。+=做我想做的,但我想了解为什么push不做。我期望的行为(并与+=一起工作):b=Array.new(3,[])b[0]+=["apple"]b[1]+=["orange"]b[2]+=["frog"]b=>[["苹果"],["橙子"],["Frog"]]通过推送,我将推送的元素附加到每个子数组(为什么?):a=Array.new(3,[])a[0].push("apple")a[1].push("orange")a[2].push("frog")a=>[[“苹果”、“橙子”、“Frog”]、[“苹果”、“橙子”、“Frog”]、[“苹果”、“
有没有办法让Ruby能够做这样的事情?classPlane@moved=0@x=0defx+=(v)#thisiserror@x+=v@moved+=1enddefto_s"moved#{@moved}times,currentxis#{@x}"endendplane=Plane.newplane.x+=5plane.x+=10putsplane.to_s#moved2times,currentxis15 最佳答案 您不能在Ruby中覆盖复合赋值运算符。任务在内部处理。您应该覆盖+,而不是+=。plane.a+=b与plane.a=