Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > sprintf a filename

Reply
Thread Tools

sprintf a filename

 
 
Rudra Banerjee
Guest
Posts: n/a
 
      09-18-2012
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?
 
Reply With Quote
 
 
 
 
Keith Thompson
Guest
Posts: n/a
 
      09-18-2012
Rudra Banerjee <(E-Mail Removed)> 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.velocityreviews.com/forums/(E-Mail Removed) <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"
 
Reply With Quote
 
 
 
 
Rudra Banerjee
Guest
Posts: n/a
 
      09-18-2012
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.
 
Reply With Quote
 
James Kuyper
Guest
Posts: n/a
 
      09-18-2012
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.
 
Reply With Quote
 
Lew Pitcher
Guest
Posts: n/a
 
      09-18-2012
On Tuesday 18 September 2012 17:01, in comp.lang.c, (E-Mail Removed)
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"
 
Reply With Quote
 
Nobody
Guest
Posts: n/a
 
      09-18-2012
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...ns/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.

 
Reply With Quote
 
Malcolm McLean
Guest
Posts: n/a
 
      09-19-2012
בתאריך יום שלישי, 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).
 
Reply With Quote
 
Ben Bacarisse
Guest
Posts: n/a
 
      09-19-2012
Malcolm McLean <(E-Mail Removed)> 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.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
The filename set in the response.setHeader("Content-Disposition", "attachment; filename=test.csv") is being ignored! Ed Java 10 07-13-2010 12:43 PM
Re: filename.gif or filename.gif.jpg? Beauregard T. Shagnasty HTML 1 05-30-2008 01:23 PM
Stitch rar files ( filename.part01 and filename.part02) Please help ixgor Software 1 10-15-2006 02:33 AM
how to get 8.3 format filename from long filename jacobyv@sis.unibe.ch Java 1 06-15-2006 10:39 AM
Extract filename from a filename typed by user =?Utf-8?B?Sm9l?= ASP .Net 1 08-23-2004 11:29 PM



Advertisments