![]() |
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? |
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" |
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. |
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. |
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" |
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. |
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). |
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 10:27 PM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.