Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.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
从printf格式字符串提取类型信息 < >我想从Prtf格式字符串中提取C++类型的信息。比如说, Input: "%10u foo %% %+6.3f %ld %s" Output: unsigned int double long char*_C++_Linux_Printf - Fatal编程技术网

从printf格式字符串提取类型信息 < >我想从Prtf格式字符串中提取C++类型的信息。比如说, Input: "%10u foo %% %+6.3f %ld %s" Output: unsigned int double long char*

从printf格式字符串提取类型信息 < >我想从Prtf格式字符串中提取C++类型的信息。比如说, Input: "%10u foo %% %+6.3f %ld %s" Output: unsigned int double long char*,c++,linux,printf,C++,Linux,Printf,我已尝试使用printf.h中的参数进行此操作,但返回的argtypes似乎不包含有关已签名/未签名的信息 还有什么方法可以获取签名/未签名的信息吗?正如我在回答中所说,parse\u printf\u格式并不是为您所需要的内容而设计的。 您可以通过以下算法自己解析它: 因为%后面的字符是修饰符或类型(不能两者都是),所以首先在字符串中搜索%字符 如果下一个字符在类型数组中('d'、's'、'f'、'g'、'u'等),则得到类型的类(指针、int、无符号、double等)。这可能足以满足您的需要

我已尝试使用printf.h中的参数进行此操作,但返回的argtypes似乎不包含有关已签名/未签名的信息


还有什么方法可以获取签名/未签名的信息吗?

正如我在回答中所说,parse\u printf\u格式并不是为您所需要的内容而设计的。 您可以通过以下算法自己解析它:

  • 因为
    %
    后面的字符是修饰符或类型(不能两者都是),所以首先在字符串中搜索
    %
    字符
  • 如果下一个字符在类型数组中('d'、's'、'f'、'g'、'u'等),则得到类型的类(指针、int、无符号、double等)。这可能足以满足您的需要
  • 如果没有,则继续下一个字符,直到找到修饰符/类型数组中不允许的一个字符
  • 如果类型的类不足以满足您的需要,则必须返回修改器以调整最终类型
  • 您可以为真正的算法使用许多实现(例如),但由于不需要验证输入字符串,因此手工操作非常简单

    伪代码:

    const char flags[] = {'-', '+', '0', ' ', '#'};
    const char widthPrec[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '*'}; // Last char is an extension
    const char modifiers[] = { 'h', 'l', 'L', 'z', 'j', 't' };
    const char types[] = { '%', 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'x', 'X', 'a', 'A', 'o', 's', 'c', 'p', 'n' }; // Last one is not wanted too
    
    const char validChars[] = { union of all arrays above };
    
    enum Type { None = 0, Int, Unsigned, Float, etc... };
    Type typesToType[] = { None, Int, Int, Unsigned, Float, Float, ... etc... }; // Should match the types array above
    
    // Expect a valid format, not validation is done
    bool findTypesInFormat(string & format, vector<Type> types)
    {
        size_t pos = 0;
        types.clear();
        while (pos < format.length())
        {
            pos = format.find_first_of('%', pos);
            if (pos == format.npos) break;
            pos++;
            if (format[pos] == '%') continue;
            size_t acceptUntilType = format.find_first_not_of(validChars, pos);
            if (pos == format.npos) pos = format.length();
            pos --;
            if (!inArray(types, format[pos])) return false; // Invalid string if the type is not what we support
    
            Type type = typesToType[indexInArray(types, format[pos])];
    
            // We now know the type, we might need to refine it
            if (inArray(modifiers, format[pos-1])
            {
                type = adjustTypeFromModifier(format[pos-1], type);
            }
            types.push_back(type);
            pos++;
        }
        return true;
    }
    
    // inArray, indexInArray and adjustTypeFromModifier are simple functions left to be written.
    
    const char flags[]={'-','+','0',''.'};
    常量字符宽度prec[]={'0','1','2','3','4','5','6','7','8','9',','.','*'};//最后一个字符是一个扩展
    常量字符修饰符[]={'h','l','l','z','j','t'};
    常量字符类型[]={“%”,d',i',u',f',f',e',e',g',g',x',x',a',a',o',s',c',p',n'};//最后一个也不需要
    const char validChars[]={上面所有数组的并集};
    枚举类型{None=0,Int,Unsigned,Float等..};
    Type typesToType[]={None,Int,Int,Unsigned,Float,Float应与上面的数组类型匹配
    //需要有效的格式,但未完成验证
    布尔findTypesInFormat(字符串和格式、向量类型)
    {
    大小\u t pos=0;
    类型。清除();
    while(pos
    正如我在回答中所说,parse\u printf\u格式并不是为您所需要的内容而设计的。 您可以通过以下算法自己解析它:

  • 因为
    %
    后面的字符是修饰符或类型(不能两者都是),所以首先在字符串中搜索
    %
    字符
  • 如果下一个字符在类型数组中('d'、's'、'f'、'g'、'u'等),那么您将得到类型的类(指针、int、无符号、double等)。这可能足以满足您的需要
  • 如果没有,则继续下一个字符,直到找到修饰符/类型数组中不允许的一个字符
  • 如果类型的类不足以满足您的需要,则必须返回修改器以调整最终类型
  • 您可以为真正的算法使用许多实现(例如),但由于不需要验证输入字符串,因此手工操作非常简单

    伪代码:

    const char flags[] = {'-', '+', '0', ' ', '#'};
    const char widthPrec[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '*'}; // Last char is an extension
    const char modifiers[] = { 'h', 'l', 'L', 'z', 'j', 't' };
    const char types[] = { '%', 'd', 'i', 'u', 'f', 'F', 'e', 'E', 'g', 'G', 'x', 'X', 'a', 'A', 'o', 's', 'c', 'p', 'n' }; // Last one is not wanted too
    
    const char validChars[] = { union of all arrays above };
    
    enum Type { None = 0, Int, Unsigned, Float, etc... };
    Type typesToType[] = { None, Int, Int, Unsigned, Float, Float, ... etc... }; // Should match the types array above
    
    // Expect a valid format, not validation is done
    bool findTypesInFormat(string & format, vector<Type> types)
    {
        size_t pos = 0;
        types.clear();
        while (pos < format.length())
        {
            pos = format.find_first_of('%', pos);
            if (pos == format.npos) break;
            pos++;
            if (format[pos] == '%') continue;
            size_t acceptUntilType = format.find_first_not_of(validChars, pos);
            if (pos == format.npos) pos = format.length();
            pos --;
            if (!inArray(types, format[pos])) return false; // Invalid string if the type is not what we support
    
            Type type = typesToType[indexInArray(types, format[pos])];
    
            // We now know the type, we might need to refine it
            if (inArray(modifiers, format[pos-1])
            {
                type = adjustTypeFromModifier(format[pos-1], type);
            }
            types.push_back(type);
            pos++;
        }
        return true;
    }
    
    // inArray, indexInArray and adjustTypeFromModifier are simple functions left to be written.
    
    const char flags[]={'-','+','0',''.'};
    const char widthPrec[]={'0','1','2','3','4','5','6','7','8','9',','.','*'};//最后一个字符是扩展名
    常量字符修饰符[]={'h','l','l','z','j','t'};
    常量字符类型[]={''','d','i','u','f','f','e','e','g','g','x','x','a','a','o','s','c','p','n};//最后一个也不需要
    const char validChars[]={上面所有数组的并集};
    枚举类型{None=0,Int,Unsigned,Float等..};
    Type typesToType[]={None,Int,Int,Unsigned,Float,Float
    //需要有效的格式,但未完成验证
    布尔findTypesInFormat(字符串和格式、向量类型)
    {
    大小\u t pos=0;
    类型。清除();
    while(pos
    这似乎很容易手工完成。但是请记住,char和type之间没有1:1映射,因为例如,当通过va_参数传递时,float被提升为double,或者/并且您可以通过“%g”或“%f”或“%a”等打印float。这还取决于您所在的平台(%I64d用于windows,而%lld用于linux)@xryl669感谢您的评论。我在linux上,不关心支持任何其他平台。当您说手工操作很容易时,您是否建议不使用parse_printf_format()之类的函数逐个字符解析字符串?您能说明一下您的用法吗