55870

Function with Variable length argument

I have following question on function with Variable length argument in C:

<strong>Case 1</strong> (Works)

myPrintf("%d %s", 24, "Hi There");

<strong>Case 2</strong> (Works)

char tempbuf[9]="Hi There";` myPrintf("%s %d", tempbuf, 24)

<strong>Case 3</strong> (Doesn't work)

myPrintf("%s %d", "Hi There", 24)

Does anyone has any idea why the case 3 doesn't work. I could see str = va_arg(ap, char *); returning 24 for this case intead of the actual string.

Code for myPrintf: (It is not fully functional though)

void myPrintf(char *fmt, ...) { int i,j,val,len; char *str; int len2; va_list ap; char tempBuf[128]; len=strlen(fmt); memset(tempBuf,0,MAX_MSZ_LEN); va_start(ap,fmt); for(i=0; i<len; i++) { switch(fmt[i]) { case '%' : i++; if( fmt[i] == 's' ) { str = va_arg(ap, char *); strcat(tempBuf, str); } else if( fmt[i]=='i' || fmt[i]=='d' ) { val=va_arg(ap,int); sprintf(str,"%d",val); strcat(tempBuf, str); } default : len2=strlen(tempBuf); tempBuf[len2]=fmt[i]; } } va_end(ap); }

}

Answer1:

In the case for %d:

sprintf(str,"%d",val);

what does str point to? If there was a %s earlier, it points to one of the format arguments, otherwise it is uninitialized -- in both cases, it points to an invalid location for writing. You need another temporary buffer to write the value into. You were just lucky that cases 1 and 2 worked.

Answer2:

Take a look at this code:

if( fmt[i]=='i' || fmt[i]=='d' ) { val=va_arg(ap,int); sprintf(str,"%d",val); strcat(tempBuf, str); }

The sprintf() call there is trying to write something to str. What is str ? When you call it like myPrintf("%s %d", "Hi There", 24) , the str will be the 2. argument, the string "Hi There". You cannot change a string literal in C, this will likely fail and might cause a crash.

When you call it like myPrintf("%s %d", tempbuf, 24), str will be tmpbuf, which is an array, which you can write to so that's fine. It only holds room for 9 bytes though, so it's easy to overflow that buffer.

You should rather just do something like

char tmp[32]; sprintf(tmp,"%d",val); strcat(tempBuf, tmp);

Answer3:

I'll go out on a limb... Put a comma after the format string for case 3.

Recommend

  • Regular expression for nested C structs
  • qsort comparison function not working
  • Allocating memory for two concatenated strings
  • Getting java.lang.IllegalStateException: This call must happen in the AWT Event Dispatch Thread! Ple
  • Find exception hiding/swallowing in C# code in VS2013
  • Why would you want to use composition in golang?
  • Call objective C macro from swift
  • Difference between two particular dates [duplicate]
  • What is the best way to join ordered arrays?
  • What is wrong with this emulation of CMPXCHG16B instruction?
  • OAuth2 flow for mobile app
  • Is the Go HTTP handler goroutine expected to exit immediately in this case?
  • How can I count unique terms in a plaintext file case-insensitively?
  • Programmatically Update Linked Named Range of excel object in MS Word (2007)
  • How to get Fully qualified domain name in unix
  • Group list of tuples by item
  • IE11 throwing “SCRIPT1014: invalid character” where all other browsers work
  • Remove final comma from string in vb.net
  • copying resource to sdcard gives a damaged file in android
  • jQuery .attr() and value
  • How to install a .deb file on a jailbroken iphone programmatically?
  • sending/ receiving email in Java
  • How to set my toolbar fixed while scrolling android
  • AT Commands to Send SMS not working in Windows 8.1
  • Windows forms listbox.selecteditem displaying “System.Data.DataRowView” instead of actual value
  • How to include full .NET prerequisite for Wix Burn installer
  • Benchmarking RAM performance - UWP and C#
  • Acquiring multiple attributes from .xml file in c#
  • How get height of the a view with gone visibility and height defined as wrap_content in xml?
  • FormattedException instead of throw new Exception(string.Format(…)) in .NET
  • How to CLICK on IE download dialog box i.e.(Open, Save, Save As…)
  • How to get Windows thread pool to call class member function?
  • apache spark aggregate function using min value
  • How can I remove ASP.NET Designer.cs files?
  • EntityFramework adding new object to nested object collection
  • Checking variable from a different class in C#
  • Sorting a 2D array using the second column C++
  • failed to connect to specific WiFi in android programmatically
  • java string with new operator and a literal
  • How can I use threading to 'tick' a timer to be accessed by other threads?