zoukankan      html  css  js  c++  java
  • 使用opencv传中文文件崩溃

    这个问题经过我的调试发现:
      程序是在
    while (*at && !isdigit(*at)) at++;  
    这个语句时crash的,但是跟进去是isdigit的问题,因为变量at的声明是char* at;  当at指向一个中文路径的时候,在传递给 isdigit时,*at类型很明显,隐式转换成为了int,因为  isdigit(int c)是这样声明的。所以这个时候一下子int c变成了一个负数:0xffffffb2,然后再往下跟进执行到 _ASSERTE((unsigned)(c + 1) <= 256);这个语句才崩溃的,因为强制转换成无符号的int,变成了一个很大的正数。明显不满足断言条件,所以程序当然crash了。
     
    以上的crash情况只有在Debug版本才会crash,Release版本就不会出问题。原因已经在微软带的CRT库的源码中看出来了
     
    结论:
       应该是我们使用的问题,中文windows默认的locale是GB2312的,我们很可能却调用ASCII版本的 isdigit函数(所以遇到中文立即crash),这已经不符合逻辑了,咱不可能手动去改变locale。
     
    下面是opencv源码中造成崩溃的函数源码(注意第三十行造成crash的语句):
     1 static char* icvExtractPattern(const char *filename, unsigned *offset)
     2 {
     3     char *name = (char *)filename;
     4 
     5     if( !filename )
     6         return 0;
     7 
     8     // check whether this is a valid image sequence filename
     9     char *at = strchr(name, '%');
    10     if(at)
    11     {
    12         int dummy;
    13         if(sscanf(at + 1, "%ud", &dummy) != 1)
    14             return 0;
    15         name = strdup(filename);
    16     }
    17     else // no pattern filename was given - extract the pattern
    18     {
    19         at = name;
    20 
    21         // ignore directory names
    22         char *slash = strrchr(at, '/');
    23         if (slash) at = slash + 1;
    24 
    25 #ifdef _WIN32
    26         slash = strrchr(at, '\');
    27         if (slash) at = slash + 1;
    28 #endif
    29 
    30         while (*at && !isdigit(*at)) at++;
    31 
    32         if(!*at)
    33             return 0;
    34 
    35         sscanf(at, "%u", offset);
    36 
    37         int size = (int)strlen(filename) + 20;
    38         name = (char *)malloc(size);
    39         strncpy(name, filename, at - filename);
    40         name[at - filename] = 0;
    41 
    42         strcat(name, "%0");
    43 
    44         int i;
    45         char *extension;
    46         for(i = 0, extension = at; isdigit(at[i]); i++, extension++)
    47             ;
    48         char places[10];
    49         sprintf(places, "%dd", i);
    50 
    51         strcat(name, places);
    52         strcat(name, extension);
    53     }
    54 
    55     return name;
    56 }

    下面是个最小的崩溃场景例子:

     1 #include<ctype.h>
     2 #include<stdio.h>
     3 
     4 
     5 int main(){
     6 
     7     char *pPath = "测试视频";
     8     #if defined (_DEBUG)
     9     if(!isdigit(*pPath)){
    10         printf("its not digit
    ");
    11     }
    12   #else
    13     if(!iswdigit(*pPath)){
    14         printf("Release its not digit
    ");
    15     }
    16   #endif
    17     return 0;
    18 }

    以下是一个测试:

     1 #include <stdio.h>
     2 #include <Windows.h>
     3 
     4 int NarrowChar() {
     5     char *pcAlpha = "";
     6     printf("pcAlpha  = 0x%08X!
    ", *pcAlpha); //0xFFFFFFB0
     7     return 0;
     8 }
     9 
    10 int WideChar() {
    11     //wchar_t *pwcAlpha = L"A";
    12     wchar_t *pwcAlpha = L"";
    13     printf("pwcAlpha  = 0x%08X!
    ", *pwcAlpha); //0x0000554A    UTF-16-little-endian
    14     //wprintf(L"pwcAlpha  = 0x%08X!
    ", *pwcAlpha); //0x0000554A
    15     return 0;
    16 }
    17 
    18 int main(void) {
    19      NarrowChar();
    20      WideChar();
    21 
    22      return 0;
    23 }

    由以上可以看出来,字符串这个前缀‘L’实质上是对字符串从ANSI字符集转换为Unicode字符集,也就是UTF-16编码。如果不加这个L前缀就是ANSI/ASCII字符集。

    以上的问题我前博文已经研究过了。

    ################################update#############################

    结论:

    经过调试测试,其实就是cvCreateFileCapture函数返回失败的原因,在opencv 2.4.9和opencv2.4.10中就有问题,就是都返回失败,而2.4.6就不会

    references:

    http://www.cppblog.com/luonjtu/archive/2009/03/13/76332.html

    http://comments.gmane.org/gmane.comp.lib.opencv.devel/1274

    http://msdn.microsoft.com/en-us/library/windows/desktop/ff381407(v=vs.85).aspx

    http://blog.csdn.net/xiaobai1593/article/details/7063535

    http://stackoverflow.com/questions/8032080/how-to-convert-char-to-wchar-t

     
  • 相关阅读:
    HearthBuddy投降插件2019-11-01的使用
    正则表达式在线分析 regex online analyzer
    Tips to write better Conditionals in JavaScript
    The fileSyncDll.ps1 is not digitally signed. You cannot run this script on the current system.
    Cannot capture jmeter traffic in fiddler
    JMETER + POST + anti-forgery token
    input type color
    HearthBuddy修改系统时间
    What are all the possible values for HTTP “Content-Type” header?
    UDK性能优化
  • 原文地址:https://www.cnblogs.com/foohack/p/4171215.html
Copyright © 2011-2022 走看看