English 中文(简体)
Find how many arguments are being used in a printf() statement
原标题:

Given some unknown input, how do you tell which variables are being substituted into a (s)printf statement?

printf("%s %s", "a", "b");     // both used
printf("%s",    "a", "b");     // only the first one used
printf( %1$s %1$s , "a", "b"); //      "        "
printf( %s %1$s , "a", "b");    //     "        "
printf( %1$s %s %1$s , "a", "b");   // "        "
printf( %2$s , "a", "b");      // only the second one used.

Checking the resultant string for the presence of the first or second variables won t help, because they could have the same value.

In my own situation, there is only ever 2 variables that could be substituted, and I need to know whether the second one is used or not.

最佳回答

Here is a bit hackish function to do it:

function printf_and_return_min_args_required(/* var args */) {
    $old_track = ini_set( track_errors ,  1 );
    $args = func_get_args();
    $args2 = array();
    $required = 100;    
    foreach ($args as $arg) {
        $args2[] = $arg;
        if (@call_user_func_array("printf", $args2)) {
            $required = count($args2) - 1;
            break;
        }
    }
    ini_set( track_errors , $old_track);
    return $required;
}

For sprintf() you might have to return array($result, $required) instead if you don t want the $result printed by the function.

问题回答

Parse the format string yourself and see how many args it expects.

EDIT: A psuedocode example (no error checking):

bool arg1used = false;
bool arg2used = false;
int unspecifiedscount = 0;
for (int i = 0; i < s.length; i++) {
    if s[i] !=  %  continue;
    switch s[i+1] {
        case  % :
            i++;
            break;
        case  s :
            if unspecifiedscount == 0 arg1used = true;
            if unspecifiedscount == 1 arg2used = true;
            break;
        case  1 :
            if s[i+2] ==  $  && s[i+3] ==  s  {
                arg1used = true;
                i+=3;
                true;
            }
            break;
        case  2 :
            if s[i+2] ==  $  && s[i+3] ==  s  {
                arg2used = true;
                i+=3;
                true;
            }
            break;
    }
}

I ve come up with a kludgey way which works in this situation, but would be interested to hear better solutions which are more generic.

if (($result = @sprintf($input, "a")) === false) {
    // need two arguments
    $result = sprintf($input, "a", "b");
} else {
    // only needed one argument
}

Basically, it just tries it with one argument, and if that didn t work, then you know it needs two.





相关问题
Brute-force/DoS prevention in PHP [closed]

I am trying to write a script to prevent brute-force login attempts in a website I m building. The logic goes something like this: User sends login information. Check if username and password is ...

please can anyone check this while loop and if condition

<?php $con=mysql_connect("localhost","mts","mts"); if(!con) { die( unable to connect . mysql_error()); } mysql_select_db("mts",$con); /* date_default_timezone_set ("Asia/Calcutta"); $date = ...

定值美元

如何确认来自正确来源的数字。

Generating a drop down list of timezones with PHP

Most sites need some way to show the dates on the site in the users preferred timezone. Below are two lists that I found and then one method using the built in PHP DateTime class in PHP 5. I need ...

Text as watermarking in PHP

I want to create text as a watermark for an image. the water mark should have the following properties front: Impact color: white opacity: 31% Font style: regular, bold Bevel and Emboss size: 30 ...

How does php cast boolean variables?

How does php cast boolean variables? I was trying to save a boolean value to an array: $result["Users"]["is_login"] = true; but when I use debug the is_login value is blank. and when I do ...

热门标签