Strtol and Glib Buffers causing appcrash - crash

I'm trying to take data read from a TCP socket with the g_io_channel_read_chars method and convert it into a long integer. I've tried using strtol, atoi, not casting ScanLine as a gchar pointer, accessing the first variable of ScanLine with ScanLine[0], declaring FilterAmount in different ways and despite that, my app still crashes on that line. Any ideas?
static gchar ScanLine[9640];
long int FilterAmount;
g_io_channel_read_chars (source, (gchar *) ScanLine,1,&BytesRead,&GlibError);
if (BytesRead != 1){
return TRUE;
}
printf("This is my string: %s\n", ScanLine);
FilterAmount = strtol(ScanLine, NULL, 10);
The output of the printf statement is "2"

strtol() takes a C string argument: this means the character array must be NULL-terminated. Yours is quite probably not. You must either add a terminator after the last byte you read or parse the digits yourself (since you know when to stop parsing).

Related

STM32 CDC_Transmit_FS: why does '\x' appear when using sprintf() or strcat()?

I am trying to send values from ADC through USB using "CDC_Transmit_FS()"
On the receiving side, I am receiving data using readline() and decoding the 'string' to 'int'
The code works fine but occasionally I receive for example, b'\x00234\n' instead of b'1234\n', which raises decoding error.
Do you know why does '\x' appear?
One more question is: Is there any smarter method to send ADC values through USB instead of converting int values to string?
I want to make the transmission faster.
thanks in advance!
uint32_t adcbuff[sample];
char endofpacket[5] = {'9', '9', '9', '9', '\n'};
char txbuff[sample*5];
while(1)
{
HAL_ADC_Start_DMA(&hadc2,(uint32_t*)adcbuff, sample);
for(i = 0; i < sample; i++)
{
sprintf (tempbuff, "%u\n", ((adcbuff[i] * 5000) / 0xFFFF)-2000);
strcat( txbuff,tempbuff);
}
strcat( txbuff,endofpacket);
CDC_Transmit_FS( (uint8_t*)txbuff, strlen(txbuff));
strcpy(txtbuff,"");
}
not enough rep to post as a comment
Usually \x is an indication of a hexadecimal value. Could it be that a non alphanumeric value is being received?
For troubleshooting, I would temporarily change
sprintf (tempbuff, "%u\n", ((adcbuff[i] * 5000) / 0xFFFF)-2000); to
sprintf (tempbuff, "%s\n", ((adcbuff[i] * 5000) / 0xFFFF)-2000); to see what kind of characters are being sent over. (Maybe sprintf to a tmp file instead.)
b'\x00234\n' - This means that first byte is 0! Not ASCII 0 = 0x30, but just 0.
Probably this is effect of strcat - after concatenating this function adds '\0' at the end of string.
Instead of using sprintf, just redirect stdout to USB-CDC and use printf:
int _write(int file, char *ptr, int len)
{
UNUSED(file);
CDC_Transmit_FS((uint8_t*)ptr, len);
while (hcdc->TxState != 0);
return len;
}
If you want to send all at once use setvbuf for stdout with _IOFBF and call fflush(stdout);

printf(), fprintf(), wprintf() and NSlog() won't print on XCode

I'm doing a small app for evaluating and analyzing transfer functions. As boring as the subject might seem to some, I want it to at least look extra cool and pro and awesome etc... So:
Step 1: Gimme teh coefficients! [A bunch of numbers]
Step 2: I'll write the polynomial with its superscripts. [The bunch of numbers in a string]
So, I write a little C parser to just print the polynomial with a decent format, for that I require a wchar_t string that I concatenate on the fly. After the string is complete I quickly try printing it on the console to check everything is ok and keep going. Easy right? Welp, I ain't that lucky...
wchar_t *polynomial_description( double *polyArray, char size, char var ){
wchar_t *descriptionString, temp[100];
int len, counter = 0;
SUPERSCRIPT superscript;
descriptionString = (wchar_t *) malloc(sizeof(wchar_t) * 2);
descriptionString[0] = '\0';
while( counter < size ){
superscript = polynomial_utilities_superscript( size - counter );
len = swprintf(temp, 100, L"%2.2f%c%c +", polyArray[counter], var, superscript);
printf("temp size: %d\n", len);
descriptionString = (wchar_t *) realloc(descriptionString, sizeof(wchar_t) * (wcslen(descriptionString) + len + 1) );
wcscat(descriptionString, temp);
counter++;
}
//fflush(stdout); //Already tried this
len = wprintf(L"%ls\n", descriptionString);
len = printf("%ls**\n", descriptionString);
len = fprintf(stdout, "%ls*\n", descriptionString);
len = printf("FFS!! Print something!");
return descriptionString;
}
During the run we can see temp size: 8 printed the expected number of times ONLY WHILE DEBUGGING, if I run the program I get an arbitrary number of prints each run. But after that, as the title states, wprintf, printf and fprintf don't print anything, yet len does change its size after each call.
In the caller function, (application:(UIApplication *)application didFinishLaunchingWithOptions:, while testing) I put an NSLog to print the return string, and I dont get ANYTHING not even the Log part.
What's happening? I'm at a complete loss.
Im on XCode 4.2 by the way.
What's the return value from printf/wprintf in the case where you think it's not printing anything? It should be returning either -1 in the case of a failure or 1 or more, since if successful, it should always print at least the newline character after the description string.
If it's returning 1 or more, is the newline getting printed? Have you tried piping the output of your program to a hex dumper such as hexdump -C or xxd(1)?
If it's returning -1, what is the value of errno?
If it turns out that printf is failing with the error EILSEQ, then what's quite likely happening is that your string contains some non-ASCII characters in it, since those cause wcstombs(3) to fail in the default C locale. In that case, the solution is to use setlocale(3) to switch into a UTF-8 locale when your program starts up:
int main(int argc, char **argv)
{
// Run "locale -a" in the Terminal to get a list of all valid locales
setlocale(LC_ALL, "en_US.UTF-8");
...
}

Signed Char to Int

Basically, my problem is a signed char to int and string conversion in cocoa.
I found this piece of code in an open source cocoa bluetooth application and am trying to apply it to my own.
Basically, I get a signed char output from the variable "RSSI", and want to convert it to an int and a string, the string for outputting to the log and the int for further calculation. However, no matter what I try, I cannot seem to get it converted, and just get an EXEC_BAD_ACCESS if I try outputting the signed char to the log as it is.
A typical value for the signed char would be " -57 '\307' " quoted directly from the process before it is held up by the NSLog. Here's the code:
- (BOOL)isInRange {
BluetoothHCIRSSIValue RSSI = 127; /* Valid Range: -127 to +20 */
if (device) {
if (![device isConnected]) {
[device openConnection];
}
if ([device isConnected]) {
RSSI = [device rawRSSI];
[device closeConnection];
NSLog(RSSI);
}
}
return (RSSI >= -60 && RSSI <= 20);
}
Thanks in advance.
NSLog() takes an NSString format string as its first argument, and an (optional) variable length list of variables for the format specifiers in the format string after that:
NSLog(#"RSSI: %c", RSSI);
What you've got now (NSLog(RSSI);) is simply wrong. It should be giving you compiler warnings like these:
warning: passing argument 1 of 'NSLog' makes pointer from integer without a cast
warning: format not a string literal and no format arguments
You should always pay attention to compiler warnings, not ignore them. Especially when your program crashes on the same line the warnings refer to, they should be a red flag to you that you've made a mistake.
As an aside, I should mention that NSLog() works very much like printf(). The two major differences are that NSLog's format string should be an Objective-C string literal (#"string"), not a standard C char string ("string"), and that the format specifier for an object is %#. %# is replaced by the string returned by calling the -description method on the object to be printed.

How do I get user input without using scanf in a console app?

I'm trying to allow users to simply hit Enter without typing anything, and use this to mean accepting a default value. scanf isn't doing what I want and the app still 'blocks': the next line of code doesn't run.
The only way is to actually type something THEN press Enter.
I tried using NSFileHandle and fileHandleWithStandardInput; however, it seems that the user is now forced to hit Ctrl-D to indicate EOF.
Someone suggested using fgets, but I cannot work out what to pass as 3rd parameter (of FILE* type). Tried stdin but it doesn't 'block'.
How do I accept input from a user, using Objective-C, and at the same time allow the user to simply hit Enter without being forced to type anything? How do I read a single line, even if that line is blank?
Assuming the code doesn't block and the next line runs immediately (as you seemed to indicate early in the question and in a comment), you have a common problem when mixing non-line-based and line-based input.
What happens is you have a newline left in the buffer, and fgets sees that, reads it, and returns, instead of doing what you really want: ignoring it, and then reading a line.
The solution is to simply do the ignoring part yourself, and then call fgets:
#include <stdio.h>
#include <string.h>
FILE* ignoreline(FILE* stream) {
for (int c; (c = fgetc(stream)) != EOF;) {
if (c == '\n') break;
}
return stream;
}
void example_use() {
char buf[1000];
ignoreline(stdin);
fgets(buf, sizeof buf, stdin);
// or, since it returns the stream, can be more compact:
fgets(buf, sizeof buf, ignoreline(stdin));
}
int main() { // error handling omitted
int n;
printf("Enter a number: ");
scanf("%d", &n);
char buf[1000];
printf("Enter a line: ");
ignoreline(stdin); // comment this line and compare the difference
fgets(buf, sizeof buf, stdin);
*strchr(buf, '\n') = '\0';
printf("You entered '%s'.\n", buf);
return 0;
}
Note that it is also common and encouraged to "pair" the ignoreline with the scanf (or other non-line-based input) to turn that into line-based input. You may want to modify it, in that case, so you can tell the difference between input of "42 abc" and "42" (in the "Enter a number" case). Some people just use fgets everywhere, then parse that line with sscanf, and while that works, it's not necessary.
I use getch(); in library conio.h
simply the program waits for any key to be pressed
If you're using Windows, you can use the ReadConsoleInput function (see MSDN for more on this) :
INPUT_RECORD keyin;
DWORD r;
while (ReadConsoleInput(GetStdHandle(STD_INPUT_HANDLE),&keyin,1,&r)) {
if (keyin.EventType!=KEY_EVENT) continue;
if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_SPACE) break; ///use these VK codes to get any key's input
if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_F1)
{
printf("You pressed F1\n");
}
if (keyin.Event.KeyEvent.wVirtualKeyCode==VK_F2)
{
printf("You pressed F2\n",);
}
}//end while loop
You don't need to hit enter after each key then.This works like a dream for me...
use getchar() to take input without using scanf function...

Arithmetic with pointer types/

Some examples of adding and subtracting similarly typed pointers, using numeric and character pointers please. Using C.
Thanks.
You can check this to know about pointer arithmetic
Here's a practical example which extracts a single character from a C string:
char charAt( char *str, size_t idx) {
if (idx > strlen (str))
return '\0';
return *(str+idx);
}
Or another, which swaps an integer in an array with the one immediately before it (with no range checking):
void swapInts( int *base, size_t idx) {
tmp = *(base+idx);
*(base+idx) = *(base+idx-1);
*(base+idx-1) = tmp;
}
In both these cases, *(pointer+offset) is identical to pointer[offfset] but using pointer arithmetic instead of array offsets:
*(str+idx) -> str[idx]
*(base+idx) -> base[idx]
*(base+idx-1] -> base[idx-1]
Warning: Don't use these verbatim in your homework, have a think about them then write your own. If you copy them verbatim, you will almost certainly be failed since your educators no doubt watch these sites as well.