?
Solved

C: sprintf w/o format specifier

Posted on 2012-09-20
5
Medium Priority
?
580 Views
Last Modified: 2012-09-20
Hello,

In "C",

I stumbled upon the following statement in our source code:

sprintf(filename, TempIndexTextFileName);

Is this statement OK? I don't know what I was thinking when I wrote it...  :)
I always use format specs e.g.

sprintf(filename, "%s",  TempIndexTextFileName);

sprintf(filename, "%-10.10s",  TempIndexTextFileName);

Thanks
0
Comment
Question by:Stephen Kairys
  • 2
  • 2
5 Comments
 
LVL 35

Assisted Solution

by:sarabande
sarabande earned 1000 total points
ID: 38418479
sprintf expects at least two arguments, a char buffer for output and a format string. for each % specifier you used in the format string you need to add the appropriate argument. so if we assume that TempIndexTextFileName doesn't contain a % specifier, the sprintf is correct and would do same as strcpy. it also has same problem as strcpy that the second string needs to be zero-terminated and the first string buffer must be big enough to take that string.

i personally would always add checks on length and size and use strncpy or strcat when the size check was ok. printf and sprintf are mighty and comfortable but they also were responsible for a good deal of bugs and security leaks of c and c++ programs.

Sara
0
 
LVL 46

Expert Comment

by:Kent Olsen
ID: 38418598
Hi Steve,

In this case, the string contained in *TempIndexTextFileName* will be written to the output stream.  However, if the string contains something that looks like a format specifier, (%s, %f, %d, %x, etc.) fprintf will try to do the substitution.  That's probably not what you want, but since this appears to be a file name it probably won't happen either.

Better would be to write the string using fputs().  It will write the string without attempting to do any kind of substitution.



Good Luck,
Kent
0
 
LVL 4

Author Comment

by:Stephen Kairys
ID: 38418776
Sara and Kent,
Thanks for your replies.

Per Kent, please clarify why you suggested using fputs() when we're dealing with a function call that essentially copies a string.

Tks.
Steve
0
 
LVL 46

Accepted Solution

by:
Kent Olsen earned 1000 total points
ID: 38418869
Hi Steve,

Sorry, I misread the question and thought you were writing to a stream, not copying a string.  But the same issues are in play.


  char *filename;
  char *TempIndexTextFileName;

//  assume that both variables are properly initialized.

  TempIndexTextFileName = "ThisIsMyFile.txt";
  sprintf(filename, TempIndexTextFileName);

  TempIndexTextFileName = "ThisNameHasFunnyCharacter%s.txt";
  sprintf(filename, TempIndexTextFielName);

The first call to sprintf (above) will work as you intend.  The results of the second call are undefined as sprintf() will attempt to perform the string substitution for %s, using whatever the next object on the stack is.  It's probably the remnant of a previous function call so it could literally be anything.  At best, it's a valid pointer to 0, which will look like an empty string and the resulting string will be the original string without the %s characters.  At worse, it's a pointer to a very long string that results in a buffer overflow.  Almost as bad is if the item on the stack is data that is not a pointer, resulting in an address error and program abort (hardware fault).

Since you want to just copy the string, the correct thing to do is use a function specifically designed to do that.  In this case, use strcpy() to copy the string or strdup() to create a copy of the string and assign the buffer to the variable.


Apologies for the confusion,
Kent
0
 
LVL 4

Author Closing Comment

by:Stephen Kairys
ID: 38418899
Thank you both for your responses. Fortunately the souce buffer would never contain a format spcifier. That said, I probably should change the call to strcpy().

Tks again.
-Steve
0

Featured Post

What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

An Outlet in Cocoa is a persistent reference to a GUI control; it connects a property (a variable) to a control.  For example, it is common to create an Outlet for the text field GUI control and change the text that appears in this field via that Ou…
Preface I don't like visual development tools that are supposed to write a program for me. Even if it is Xcode and I can use Interface Builder. Yes, it is a perfect tool and has helped me a lot, mainly, in the beginning, when my programs were small…
The goal of this video is to provide viewers with basic examples to understand opening and writing to files in the C programming language.
The goal of this video is to provide viewers with basic examples to understand how to create, access, and change arrays in the C programming language.
Suggested Courses

840 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question