How to code the sprintf_s method in C - printf

like the topic, I have no idea where to start with coding the sprintf_s method.
I tried to solve it with switch-case, but again, I have no idea where to start.
Thanks for helping!

Here's where you start:
Documentation
int sprintf_s(
char *buffer,
size_t sizeOfBuffer,
const char *format, ...)
{
int ret_val = 0;
[...Fill stuff in here...]
return ret_val;
}

Related

A question about usage of kernel API method kstrtol()

int kstrtol ( const char * s,
unsigned int base,
long * res);
Can someone advise me on whether I need to allocate memory for long * res before invoking this kernel API method? I couldn't find a clear answer online.
TIA
Vinod
yes, the res should point a allocated memory, for example:
long value;
const char *buf;
.... ....
kstrtol(buf, 10, &value);

Stm32 freertos, all variable can not be change in my project

I don't understand why freertos do not allow to change extern variables
(myData)
here is my poject
file main.c
uint16_t Mydata = 0;
main()
{
System_Init();
xTaskCreate(Task1, (const char*)"Task1", 100, NULL, 4, NULL);
xTaskCreate(Task2, (const char*)"Task2", 100, NULL, 3, NULL);
vTaskStartScheduler();
}
file Task1.c
extern uint16_t Mydata;
void Task1(void *p)
{
while(1)
{
vTaskDelay(10);
printf("Result: %d", Mydata);
}
}
file Task2.c
extern uint16_t Mydata;
void Task2(void *p)
{
while(1)
{
Mydata++;
vTaskDelay(10);
}
}
but the result is never correct
most of result is like "13842930", "-18234952", or something like that !
can anyone tell me why?
(I'm sorry because of my bad English)
thank for your help !
You cannot use %d for printing a value of uint16_t. %d expects an int. You either have to cast your value to int in the printf() call (printf("Result: %d", (int)Mydata);), or use proper specifier (printf("Result: %" PRIu16 "", Mydata);). The second solution might not be supported by your toolchain.
http://en.cppreference.com/w/cpp/io/c/fprintf
Your variable should be declared volatile, otherwise compiler may as well read it once an never update the value from RAM.

Why _vsnprintf crash at windows

When will the _vsnprintf crash?
I use it like this:
void My_Printf(const char *szFormatString, ...)
{
va_list my_args;
va_start(my_args, szFormatString);
AppendToLog(szFormatString, my_args);
va_end(my_args);
}
static void AppendToLog(const char *szFormatString, va_list argptr)
{
char szLine[MAX_LENGTH_STRING] = {0};
if ((NULL != szFormatString) && (0 != strcmp(szFormatString, ""))) {
if (strlen(szFormatString) > MAX_LENGTH_STRING) {
return;
}
#ifdef WIN32
_vsnprintf(szLine, MAX_LENGTH_STRING-1, szFormatString, argptr);
#endif
...
}
and the VC show that it was broken at:
_VALIDATE_RETURN( (ch != _T('\0')), EINVAL, -1); (output.c)
I don't know why.
According to MSND, it should return a value whether it was ok or not.
This is canonical code for using vsnprintf:
void Format( const char * fmt, ... ) {
const int BUFSIZE = 1024;
char buffer[BUFSIZE];
va_list valist;
va_start( valist, fmt );
vsnprintf( &buf[0], BUFSIZE, fmt, valist );
va_end( valist );
// do something with buffer
}
I don't know if this helps, but keep in mind that vsnprintf (and _vsnprintf I guess since Microsoft says they're identical) return different values on Windows and Unix. The Windows version returns -1 if you overflow the buffer, while the Unix version returns how many characters would have been written had the buffer been large enough. Here's a couple of links that I found helpful in this regard:
http://msdn.microsoft.com/en-us/library/1kt27hek(v=vs.80).aspx
http://bytes.com/topic/c/answers/590845-snprintf-return-value
EDIT: And here's an alternate version I found to get around this problem:
http://article.gmane.org/gmane.comp.version-control.git/75280/

AccessViolation, when calling C++-DLL from C++/CLI

I've written a C++/CLI wrapper for a C++-DLL to use this DLL in a C# programm.
However, when I call a function, which takes a char* I get a AccessViolation
int Wrapper::Net_methodX(int a, String^ key, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(key);
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
int val = methodX(a,cKey, v); // AccessViolation here
Marshal::FreeHGlobal(ptr);
return val;
}
The signature of the C++-function is
int methodX(int a, char *Key, long v);
EDIT 1
Just to "pin" like the following didn't work either:
int Wrapper::Net_methodX(int a, String^ key, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(key);
char* cKey = static_cast<char*>(ptr.ToPointer());
pin_ptr<char> pinned = cKey;
int val = methodX(a,cKey, v);
Marshal::FreeHGlobal(ptr);
return val;
}
EDIT 1 END
EDIT 2
I tried also PtrToStringChars the following way (Thanks Matt, found also some doc here):
int Wrapper::Net_methodX(int a, String^ key, long v)
{
pin_ptr<const wchar_t> wkey = PtrToStringChars(key);
size_t convertedChars = 0;
size_t sizeInBytes = ((key->Length + 1) * 2);
errno_t err = 0;
char * ckey = (char * ) malloc(sizeInBytes);
err = wcstombs_s(&convertedChars, ckey, sizeInBytes, wkey, sizeInBytes);
int val = methodX(A_Symbol_Table,ckey, Value);
return val;
}
AccessViolation still occurs, maybe it's an error in methodX() (which is a Third-party-DLL).
EDIT 2 END
I have read some related questions here, but did not find a solution yet.
Any hints?
Thank you.
I know this is an old question, but for anyone who stumble upon this question looking for an answer, here are some simpler solutions.
Simply use sprintf to do the conversion like this: sprintf(cStr, "%s", clrString);. See my answer to this question for a complete example.
Read KB311259 as suggested by Matt Smith. If you are using VS 2008 or higher, use marshal_as<> (Method #4 in the KB). It's much simpler than the other methods in that document.
Simon,
I tried out your example and I do not get an Access Violation. Here's my code:
using namespace System;
using namespace System::Runtime::InteropServices;
ref class Wrapper
{
public:
static int Net_methodX(int a, String^ key, long v);
};
int methodX(int a, char * pKey, long v)
{
IntPtr ptr = static_cast<IntPtr>(pKey);
String ^ pString = Marshal::PtrToStringAnsi(ptr);
System::Console::WriteLine(pString);
return a;
}
int Wrapper::Net_methodX(int a, String^ pKey, long v)
{
IntPtr ptr = Marshal::StringToHGlobalAnsi(pKey);
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
int val = methodX(a,cKey, v); // AccessViolation here
Marshal::FreeHGlobal(ptr);
return val;
}
void main()
{
Wrapper wrapper;
String ^ p = gcnew String("Hello");
wrapper.Net_methodX(0, p, 0);
}
Also, I have a few comments:
Read here: http://support.microsoft.com/kb/311259
You are using a pin_ptr to native memory. The StringToHGlobalAnsi method returns native memory, so I don't think using a pin_ptr makes sense here. A pin_ptr would make sense if you were using a method that gives you back a pointer to managed memory (like PtrToStringChars). Unless you are modifying the string, you probably want to go with the PtrToStringChars approach anyways--to avoid unnecessary allocation and copying.
Would you post an example version of methodX that causes the problem? If I can reproduce the issue, I might be able to be more helpful.
Simon
I think there is a problem with the following code
pin_ptr<char> cKey = static_cast<char*>(ptr.ToPointer());
You might want to read this http://social.msdn.microsoft.com/forums/en-US/vclanguage/thread/0bd049fe-844a-4cb6-b9f6-c8f5107bc957
Let me know if it helped you.
Sujay

Expected identifier or '(' before '.' token

I'm new to Objective-C so I'm using a book to get to grips with it. I'm at a bit where it's explaining structs and I can't for the life of me get them to work.
I have the following code:
int main (int argc, char *argv[])
{
struct node
{
int nodeID;
int x;
int y;
BOOL isActive;
};
typedef struct node myNode;
myNode.nodeID = 1;
}
and I'm getting the error written in the title. Every time I search for this error online I found different variations such as 'before '>' token' or 'before '}' token' but i can't find anything with the '.' token and it's really frustrating and I assume it's somethings ridiculously trivial and basic. Any help would be appreciated.
I believe you're trying to modify the actual type itself. nodeA is now the type of that struct, much like int. You need to do something like nodeA myNode, then you would be able to perform myNode.nodeID = 1 without error.
I've got it sorted now, I used the following and it seems to be fixed now:
int main (int argc, char *argv[])
{
struct node
{
int nodeID;
int x;
int y;
BOOL isActive;
};
struct node myNode;
myNode.nodeID = 1;
myNode.x = 100;
myNode.y = 200;
myNode.isActive = TRUE;
}
Thanks for all your help Darth! :)
I think the problem with the original code was, it was trying to make myNode a type name using typedef. Thus, myNode is NOT a variable that assignment can happen to. Rather, it was another alias for struct node.