Why _vsnprintf crash at windows - printf

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/

Related

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.

Determine types from a variadic function's arguments in C

I'd like a step by step explanation on how to parse the arguments of a variadic function
so that when calling va_arg(ap, TYPE); I pass the correct data TYPE of the argument being passed.
Currently I'm trying to code printf.
I am only looking for an explanation preferably with simple examples but not the solution to printf since I want to solve it myself.
Here are three examples which look like what I am looking for:
https://stackoverflow.com/a/1689228/3206885
https://stackoverflow.com/a/5551632/3206885
https://stackoverflow.com/a/1722238/3206885
I know the basics of what typedef, struct, enum and union do but can't figure out some practical application cases like the examples in the links.
What do they really mean? I can't wrap my brain around how they work.
How can I pass the data type from a union to va_arg like in the links examples? How does it match?
with a modifier like %d, %i ... or the data type of a parameter?
Here's what I've got so far:
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "my.h"
typedef struct s_flist
{
char c;
(*f)();
} t_flist;
int my_printf(char *format, ...)
{
va_list ap;
int i;
int j;
int result;
int arg_count;
char *cur_arg = format;
char *types;
t_flist flist[] =
{
{ 's', &my_putstr },
{ 'i', &my_put_nbr },
{ 'd', &my_put_nbr }
};
i = 0;
result = 0;
types = (char*)malloc( sizeof(*format) * (my_strlen(format) / 2 + 1) );
fparser(types, format);
arg_count = my_strlen(types);
while (format[i])
{
if (format[i] == '%' && format[i + 1])
{
i++;
if (format[i] == '%')
result += my_putchar(format[i]);
else
{
j = 0;
va_start(ap, format);
while (flist[j].c)
{
if (format[i] == flist[j].c)
result += flist[i].f(va_arg(ap, flist[i].DATA_TYPE??));
j++;
}
}
}
result += my_putchar(format[i]);
i++;
}
va_end(ap);
return (result);
}
char *fparser(char *types, char *str)
{
int i;
int j;
i = 0;
j = 0;
while (str[i])
{
if (str[i] == '%' && str[i + 1] &&
str[i + 1] != '%' && str[i + 1] != ' ')
{
i++;
types[j] = str[i];
j++;
}
i++;
}
types[j] = '\0';
return (types);
}
You can't get actual type information from va_list. You can get what you're looking for from format. What it seems you're not expecting is: none of the arguments know what the actual types are, but format represents the caller's idea of what the types should be. (Perhaps a further hint: what would the actual printf do if a caller gave it format specifiers that didn't match the varargs passed in? Would it notice?)
Your code would have to parse the format string for "%" format specifiers, and use those specifiers to branch into reading the va_list with specific hardcoded types. For example, (pseudocode) if (fspec was "%s") { char* str = va_arg(ap, char*); print out str; }. Not giving more detail because you explicitly said you didn't want a complete solution.
You will never have a type as a piece of runtime data that you can pass to va_arg as a value. The second argument to va_arg must be a literal, hardcoded specification referring to a known type at compile time. (Note that va_arg is a macro that gets expanded at compile time, not a function that gets executed at runtime - you couldn't have a function taking a type as an argument.)
A couple of your links suggest keeping track of types via an enum, but this is only for the benefit of your own code being able to branch based on that information; it is still not something that can be passed to va_arg. You have to have separate pieces of code saying literally va_arg(ap, int) and va_arg(ap, char*) so there's no way to avoid a switch or a chain of ifs.
The solution you want to make, using the unions and structs, would start from something like this:
typedef union {
int i;
char *s;
} PRINTABLE_THING;
int print_integer(PRINTABLE_THING pt) {
// format and print pt.i
}
int print_string(PRINTABLE_THING pt) {
// format and print pt.s
}
The two specialized functions would work fine on their own by taking explicit int or char* params; the reason we make the union is to enable the functions to formally take the same type of parameter, so that they have the same signature, so that we can define a single type that means pointer to that kind of function:
typedef int (*print_printable_thing)(PRINTABLE_THING);
Now your code can have an array of function pointers of type print_printable_thing, or an array of structs that have print_printable_thing as one of the structs' fields:
typedef struct {
char format_char;
print_printable_thing printing_function;
} FORMAT_CHAR_AND_PRINTING_FUNCTION_PAIRING;
FORMAT_CHAR_AND_PRINTING_FUNCTION_PAIRING formatters[] = {
{ 'd', print_integer },
{ 's', print_string }
};
int formatter_count = sizeof(formatters) / sizeof(FORMAT_CHAR_AND_PRINTING_FUNCTION_PAIRING);
(Yes, the names are all intentionally super verbose. You'd probably want shorter ones in the real program, or even anonymous types where appropriate.)
Now you can use that array to select the correct formatter at runtime:
for (int i = 0; i < formatter_count; i++)
if (current_format_char == formatters[i].format_char)
result += formatters[i].printing_function(current_printable_thing);
But the process of getting the correct thing into current_printable_thing is still going to involve branching to get to a va_arg(ap, ...) with the correct hardcoded type. Once you've written it, you may find yourself deciding that you didn't actually need the union nor the array of structs.

Storing int values in an uint8_t array in code composer studio vs 5.4

I have a string in a uint8_t str[] array and I am trying to store the positions of characters within the str in another variable called uint8_t pos[]. The code is written in Code Composer Studio vs 5.4
I tried using sprintf(), type casting as well as changing the type of uint8_t pos[] to int pos[] as well as unsigned int pos[]. None of these work.
The code breaks at the sprintf statement and comes to a halt by reaching an undefined memory location. When I run in assembly after reaching sprintf statement, it gives an error saying that a source code for sprint.c cannot be found in location.
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "tm4c123gh6pm.h"
#include <stdio.h>
void initHw()
{
.
.
}
int main(void)
{
// Initialize hardware
initHw();
char strRx[80];
int count =0;
int count_enter=0;
uint8_t posStr[80];
uint8_t typeStr[80];
int pos=0;
int len;
unsigned int j=0, argCount=0;
while(1)
{
if(count == 0)
{
putsUart0("Enter characters for the string\r\n");
}
if(count <= 80)
{
char c = getcUart0();
if(c=='\b')
if(count>0)
count--;
else
break;
if(c>=' ')
{
strRx[count]=c;
count++;
}
if(count==80 || c==13)//'\r')
{
count_enter++;
if(count_enter==1) //count==80 before carriage return
{
len = count;
strRx[count]='\0';
while(count!=80)
strRx[count++]='\0';
count_enter=0;
putsUart0("\r\nEntered string is:\r\n");
putsUart0(strRx);
putsUart0("\r\n");
}
j=0;
//char a[10];
for(pos=0; pos!=len; pos++)// strRx[pos]!='\0'; pos++)
{
char a[80];
if((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z'))
{
typeStr[j]='a';
//posStr[j]=pos;
a[j]=pos;
sprintf(a,"%u",pos); //source not found
//a[j]=pos;
//posStr[j]=sprintf("%c",a);
//posStr[j]=(uint8_t)a;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='A' && strRx[pos]<='Z') || (strRx[pos]>='a' && strRx[pos]<='z')))
{
pos++;
}
pos--;
j++;
}
else if(strRx[pos]>='0' && strRx[pos]<='9')
{
typeStr[j]='n';
a[j]=pos;
sprintf(a,"%u",pos);
//posStr[j]=pos;//a;
while(strRx[pos]!='\0'&&((strRx[pos]>='0' && strRx[pos]<='9')))
{
pos++;
}
pos--;
j++;
}
else
{
while(strRx[pos]!='\0'&&((strRx[pos]<'A' && strRx[pos]>'Z') && (strRx[pos]<'a' && strRx[pos]>'z') && (strRx[pos+1]<'0' && strRx[pos+1]>'9')))
pos++;
}
}
argCount=j;
while(j!=80)
{
typeStr[j++]='\0';
posStr[j++]='\0';
}
count = 0;
}//if(count==80 || c==13)//'\r')
}//if count<=80
}//while(1)
}//main
The "unable to locate sprintf.c" error probably just means that the debugger cannot locate the source file, which means it cannot show the source code in the debugger window. It's possible that you don't have the source code for sprintf.c and all you have is the precompiled library. Or maybe you do have the source code and the debugger is simply looking in the wrong path. If you have the source code then there may be a way to tell the debugger which path to find it.
But that is just a debugger display issue -- It is not what is causing your program to crash. The problem may be in your code but you'd have to share your code for us to identify that. Or the problem may be a couple other issues that can occur with the printf related routines.
1) printf routines can use a relatively large amount of stack space. So check for a stack overflow and increase the stack size if necessary.
2) Some embedded libraries provide multiple implementations of the printf routines such as "small", "no-float", and "full". The limited implementations use less code space but don't support all of the format specifiers. So make sure the implementation of sprintf that you've linked with supports all the format specifiers that you're actually using. Look through the project settings under linker or libraries for an option to select which version of printf is used.

Stange behavior with my C string reverse function

I'm just an amateur programmer...
And when reading, for the second time, and more than two years apart, kochan's "Programming in Objective-C", now the 6th ed., reaching the pointer chapter i tried to revive the old days when i started programming with C...
So, i tried to program a reverse C string function, using char pointers...
At the end i got the desired result, but... got also a very strange behavior, i cannot explain with my little programming experience...
First the code:
This is a .m file,
#import <Foundation/Foundation.h>
#import "*pathToFolder*/NSPrint.m"
int main(int argc, char const *argv[])
{
#autoreleasepool
{
char * reverseString(char * str);
char *ch;
if (argc < 2)
{
NSPrint(#"No word typed in the command line!");
return 1;
}
NSPrint(#"Reversing arguments:");
for (int i = 1; argv[i]; i++)
{
ch = reverseString(argv[i]);
printf("%s\n", ch);
//NSPrint(#"%s - %s", argv[i], ch);
}
}
return 0;
}
char * reverseString(char * str)
{
int size = 0;
for ( ; *(str + size) != '\0'; size++) ;
//printf("Size: %i\n", size);
char result[size + 1];
int i = 0;
for (size-- ; size >= 0; size--, i++)
{
result[i] = *(str + size);
//printf("%c, %c\n", result[i], *(str + size));
}
result[i] = '\0';
//printf("result location: %lu\n", result);
//printf("%s\n", result);
return result;
}
Second some notes:
This code is compiled in a MacBook Pro, with MAC OS X Maverick, with CLANG (clang -fobjc-arc $file_name -o $file_name_base)
That NSPrint is just a wrapper for printf to print a NSString constructed with stringWithFormat:arguments:
And third the strange behavior:
If I uncomment all those commented printf declarations, everything work just fine, i.e., all printf functions print what they have to print, including the last printf inside main function.
If I uncomment one, and just one, randomly chosen, of those comment printf functions, again everything work just fine, and I got the correct printf results, including the last printf inside main function.
If I leave all those commented printf functions as they are, I GOT ONLY BLANK LINES with the last printf inside main block, and one black line for each argument passed...
Worst, if I use that NSPrint function inside main, instead of the printf one, I get the desired result :!
Can anyone bring some light here please :)
You're returning a local array, that goes out of scope as the function exits. Dereferencing that memory causes undefined behavior.
You are returning a pointer to a local variable of the function that was called. When that function returns, the memory for the local variable becomes invalid, and the pointer returned is rubbish.

how implement function work as sprintf use wchar for parameter?

l used ANDROID NDK 。so l want to format something。just use sprintf,but l can not use it with
wchar_t. is there some helps for me?
You probably want swprintf and friends, assuming Android has it like Posix and Linux systems.
Glib (from GTK) has functions for unicode manipulation and for string utilities. I believe you should be able to make it work on Android.
In Android OS NDK versions before 5.0 ("Lollipop"), the sprintf() does not support the "%ls" (wchar_t pointer) format specifier. Thus, the following statement compiles but does not execute correctly under NDK (pre-5.0):
char buffer [1000];
wchar_t *wp = L"wide-char text";
sprintf (buffer, "My string is: %ls", wp);
The workaround is to convert the wchar_t string to UTF-8 (which is a char *) using any one of the Open Source wide-to-utf8 implementations (e.g. the UTF8-CPP project), passing its pointer to sprintf:
// WcharToUtf8: A cross-platform function I use for converting wchar_t string
// to UTF-8, based on the UTF8-CPP Open Source project
bool WcharToUtf8 (std::string &dest, const wchar_t *src, size_t srcSize)
{
bool ret = true;
dest.clear ();
size_t wideSize = sizeof (wchar_t);
if (wideSize == 2)
{
utf8::utf16to8 (src, src + srcSize, back_inserter (dest));
}
else if (wideSize == 4)
{
utf8::utf32to8 (src, src + srcSize, back_inserter (dest));
}
else
{
// sizeof (wchar_t) is not 2 or 4 (does it equal one?)! We didn't
// expect this and need to write code to handle the case.
ret = false;
}
return ret;
}
...
char buffer [1000];
wchar_t wp = L"wide-char text";
std::string utf8;
WcharToUtf8 (utf8, wp, wcslen (wp));
sprintf (buffer, "My string is: %s", utf8.c_str ());
Starting with Android 5.0 ("Lollipop"), sprintf() supports the "%ls" format specifier, so the original sprintf() code above works correctly.
If your Android NDK code needs to run on all version of Android, you should wrap all your wchar_t pointers passed to sprintf with a macro like the following:
#define CONVERTFORANDROID(e) (GetSupportsSprintfWideChar () ? (void *) e : (void *) WcharToUtf8(e).c_str ())
char buffer [1000];
wchar_t *wp = L"wide-char text";
sprintf (buffer, "My string is: %ls", CONVERTFORANDROID(wp));
The GetSupportsSprintfWideChar() function should be a local function that returns true if the running Android OS is 5.0 or above, while returning false if the OS is pre-5.0.