sprintf a filename

Discussion in 'C Programming' started by Rudra Banerjee, Sep 18, 2012.

  1. I am trying to have something like:
    Code:

    char pdfinfo[1028];
    sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    g_print("%s", pdfinfo);
    system((char *) pdfinfo);


    This works fine when the filename choosen has no space. If it has space,
    as linux reads it as "file\ with\ space", pdfinfo is giving error.

    I cannot open pdfinfo (in my knowledge) with fopen, as then,

    sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);

    will give error, as I am printing a FILE as char.
    what is the way out?
    Rudra Banerjee, Sep 18, 2012
    #1
    1. Advertising

  2. Rudra Banerjee <> writes:
    > I am trying to have something like:
    > Code:
    >
    > char pdfinfo[1028];
    > sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    > g_print("%s", pdfinfo);
    > system((char *) pdfinfo);


    The cast is unnecessary, and could be dangerous if you got it wrong.
    Since pdfinfo is a char array, it's implicitly converted to a char*
    in most contexts. If you're unclear on this, read section 6 of the
    comp.lang.c FAQ, <http://www.c-faq.com/>.

    > This works fine when the filename choosen has no space. If it has space,
    > as linux reads it as "file\ with\ space", pdfinfo is giving error.
    >
    > I cannot open pdfinfo (in my knowledge) with fopen, as then,
    >
    > sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    >
    > will give error, as I am printing a FILE as char.
    > what is the way out?


    The behavior of system() is largely system-specific.

    On Unix-like systems, it executes the given command by passing it as an
    argument to /bin/sh. That means that, to run a command with certain
    arguments using system(), the argument needs to be the same as what
    you'd need to type at a shell prompt.

    This is likely to work:

    sprintf(pdfinfo, "pdfinfo '%s' >filout", pdfname);

    But it's not a completely general solution; for example, it will
    fail if pdfname contains a single-quote character.

    If there's a general solution, you're more likely to find it on
    comp.unix.programmer. (I'm assuming you're using a Unix-like system;
    if you're not, then another newsgroup might be more helpful.)

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Will write code for food.
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
    Keith Thompson, Sep 18, 2012
    #2
    1. Advertising

  3. Keith,
    Thanks for your help. For my present situation, its working. For a "failsafe" way, I have asked comp.unix.programmer as per your advice.
    Rudra Banerjee, Sep 18, 2012
    #3
  4. Rudra Banerjee

    James Kuyper Guest

    On 09/18/2012 05:01 PM, Rudra Banerjee wrote:
    > I am trying to have something like:
    > Code:
    >
    > char pdfinfo[1028];
    > sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    > g_print("%s", pdfinfo);
    > system((char *) pdfinfo);
    >
    >
    > This works fine when the filename choosen has no space. If it has space,
    > as linux reads it as "file\ with\ space", pdfinfo is giving error.


    When you call system(), the host environment's command processor (if one
    is available) is used to process the string. I believe that on Unix-like
    systems it's usually
    "/bin/sh -c", which on Linux systems is usually an alias for bash. The
    problem is not the presence of a backslash, but the absence of one.

    Try these two:
    system("pdfinfo file with space");
    system("pdfinfo file\\ with\\ space");

    On my system, the first fails, the second succeeds. Keep in mind that
    '\\' is a C escape sequence that only places a single backslash
    character in the resulting string. A space character in bash normally
    separates command line arguments. Escaping it with a backslash turns
    that special meaning off, with the result that the entire file name,
    including the embedded spaces, is parsed as a single command line
    argument to be passed to pdfinfo. As Keith pointed out, the following
    also works:
    system("pdfinfo 'file with space'");

    > I cannot open pdfinfo (in my knowledge) with fopen, as then,
    >
    > sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    >
    > will give error, as I am printing a FILE as char.
    > what is the way out?


    One way is to insert a backslash into the file name before any spaces,
    or to surround it with single quotes, before calling system().

    If you need to look at files with other unusual characters embedded in
    them (such as backslashes, single quotes, etc.), you may need a more
    complete solution. You might want to look at the exec*() family of POSIX
    functions - they pass the specified list of arguments directly to the
    program being executed, without any command line processing. You'll need
    to use fork() before calling it, and only call the exec*() function in
    the child processif there's anything you want the program to do after
    calling it.
    James Kuyper, Sep 18, 2012
    #4
  5. Rudra Banerjee

    Lew Pitcher Guest

    On Tuesday 18 September 2012 17:01, in comp.lang.c,
    wrote:

    > I am trying to have something like:
    > Code:
    >
    > char pdfinfo[1028];
    > sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    > g_print("%s", pdfinfo);
    > system((char *) pdfinfo);
    >
    >
    > This works fine when the filename choosen has no space. If it has space,
    > as linux reads it as "file\ with\ space", pdfinfo is giving error.


    Is there any particular reason why you restrict yourself to the system()
    function here?

    You mention that you are working on a Linux system, and you call a function
    not defined in the C standard (g_print()), so it appears that you have no
    reason /not/ to use Linux-specific functions (that is, the standard POSIX
    process management functions) to run your "pdfinfo" program.

    You might want to discuss your code, and the alternatives, in the
    comp.os.linux.development.apps or comp.unix.programmer newsgroups. We can
    help you there with examples of POSIX functions that would make easy work
    of your problem here.


    --
    Lew Pitcher
    "In Skills, We Trust"
    Lew Pitcher, Sep 18, 2012
    #5
  6. Rudra Banerjee

    Nobody Guest

    On Tue, 18 Sep 2012 14:01:14 -0700, Rudra Banerjee wrote:

    > I am trying to have something like:
    > Code:
    >
    > char pdfinfo[1028];
    > sprintf(pdfinfo, "pdfinfo %s >filout", pdfname);
    > g_print("%s", pdfinfo);
    > system((char *) pdfinfo);
    >
    >
    > This works fine when the filename choosen has no space. If it has space,
    > as linux reads it as "file\ with\ space", pdfinfo is giving error.


    Don't use system().

    For Unix, use fork() and one of the exec*() functions. This ensures
    that the resulting program's argv[] will be exactly what you want it to
    be. You'll need to implement redirection manually with dup2(). As a
    starting point, you might consider using the sample system()
    implementation given at:

    http://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html

    Note that most of it is signal handling: in the parent, SIGINT and SIGQUIT
    are ignored and SIGCHLD is blocked. This may or may not be appropriate for
    your particular case (this behaviour results in Ctrl-C killing the child
    process rather than the parent; this can be appropriate for long-running
    programs, particularly interactive ones, but often isn't for simple
    commands).

    Windows doesn't have an equivalent; the underlying interface for passing
    arguments between programs uses a single string rather than a list of
    strings. For programs using C's main() interface, the executable is
    responsible for parsing the command string into the argv[]. In theory
    there's no reliable way to force the program's main() (if it even has one)
    to receive a specific argument list. The best you can do is assume that
    it uses the syntax documented at:

    http://msdn.microsoft.com/en-us/library/17w5ykft.aspx

    BTW: don't use the spawn*() functions. They have the correct interface,
    but the wrong implementation; they just concatenate the arguments with
    spaces in between, with no quoting. So you'll just get the existing
    incorrect behaviour if the filename contains spaces or other
    metacharacters.
    Nobody, Sep 18, 2012
    #6
  7. בת×ריך ×™×•× ×©×œ×™×©×™, 18 בספטמבר 2012 22:01:14 UTC+1, מ×ת Rudra Banerjee:
    > I am trying to have something like:
    >
    > This works fine when the filename choosen has no space. If it has space,
    > as linux reads it as "file\ with\ space", pdfinfo is giving error.
    >

    So you need quotes around the filename, so the shell expands it as one string
    instead of two. (Embed quotes using the backslash to escape).
    Malcolm McLean, Sep 19, 2012
    #7
  8. Malcolm McLean <> writes:

    > בת×ריך ×™×•× ×©×œ×™×©×™, 18 בספטמבר 2012 22:01:14 UTC+1, מ×ת Rudra Banerjee:
    >> I am trying to have something like:
    >>
    >> This works fine when the filename choosen has no space. If it has space,
    >> as linux reads it as "file\ with\ space", pdfinfo is giving error.
    >>

    > So you need quotes around the filename, so the shell expands it as one string
    > instead of two. (Embed quotes using the backslash to escape).


    In comp.lang.c you can't say what sort of quoting and/or escaping is
    needed. If (as turns out to be the case) the OP can assume a certain
    shell with be involved you can give a defintite answer (see
    comp.unix.programmer for the definitive answer in this case).

    --
    Ben.
    Ben Bacarisse, Sep 19, 2012
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?Sm9l?=

    Extract filename from a filename typed by user

    =?Utf-8?B?Sm9l?=, Aug 23, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    1,006
    Travis Murray
    Aug 24, 2004
  2. Replies:
    1
    Views:
    1,437
    Roland de Ruiter
    Jun 15, 2006
  3. Ed
    Replies:
    10
    Views:
    45,751
    alok000707
    Jul 13, 2010
  4. Beauregard T. Shagnasty

    Re: filename.gif or filename.gif.jpg?

    Beauregard T. Shagnasty, May 30, 2008, in forum: HTML
    Replies:
    1
    Views:
    736
    Jonathan N. Little
    May 30, 2008
  5. Bergamot
    Replies:
    0
    Views:
    435
    Bergamot
    May 30, 2008
Loading...

Share This Page