Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   sprintf a filename (http://www.velocityreviews.com/forums/t952385-sprintf-a-filename.html)

Rudra Banerjee 09-18-2012 09:01 PM

sprintf a filename
 
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?

Keith Thompson 09-18-2012 09:11 PM

Re: sprintf a filename
 
Rudra Banerjee <bnrj.rudra@gmail.com> 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) kst-u@mib.org <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"

Rudra Banerjee 09-18-2012 09:44 PM

Re: sprintf a filename
 
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.

James Kuyper 09-18-2012 09:55 PM

Re: sprintf a filename
 
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.

Lew Pitcher 09-18-2012 10:19 PM

Re: sprintf a filename
 
On Tuesday 18 September 2012 17:01, in comp.lang.c, bnrj.rudra@gmail.com
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"

Nobody 09-18-2012 10:38 PM

Re: sprintf a filename
 
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.


Malcolm McLean 09-19-2012 03:40 PM

Re: sprintf a filename
 
בתאריך יום שלישי, 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).

Ben Bacarisse 09-19-2012 07:41 PM

Re: sprintf a filename
 
Malcolm McLean <malcolm.mclean5@btinternet.com> 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.


All times are GMT. The time now is 04:59 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.