Different sizes of same strings - Telnet programming - iphone

I have been trying to create an iphone app sending telnet command. However what puzzling me is that the sizes of certain strings are so much different, particularly when they include \n or \r. I listed out a few examples. Please assist.
const char *a = "play 25\n";
int sizeBitA1 = sizeof(a); // 8 units
int sizeBitA2 = sizeof("play 25\n"); // 9 units
const char *b = "\r\n";
int sizeBitB1 = sizeof(b); // 8 units
int sizeBitB2 = sizeof("\r\n"); // 3 units

The following code snippet illustrates all the options of using string constants, arrays and pointers, and sizeof and strlen.
const char *a = "play\n";
const char at[] = "play\n";
int sizeBitA1 = sizeof(a); // 8 bytes == size of a pointer
int sizeBitA2 = sizeof("play\n"); // 6 bytes, including the trailing '\0'
int sizeBitA3 = sizeof(at); // 6 bytes, including the trailing '\0'
int sizeBitA4 = strlen(a); // 5 bytes, excluding the trailing '\0'
int sizeBitA5 = strlen("play\n"); // 5 bytes, excluding the trailing '\0'
int sizeBitA6 = strlen(at); // 5 bytes, excluding the trailing '\0'
const char *b = "\r\n";
const char bt[] = "\r\n";
int sizeBitB1 = sizeof(b); // 8 bytes == size of a pointer
int sizeBitB2 = sizeof("\r\n"); // 3 bytes, including the trailing '\0'
int sizeBitB3 = sizeof(bt); // 3 bytes, including the trailing '\0'
int sizeBitB4 = strlen(b); // 2 bytes, excluding the trailing '\0'
int sizeBitB5 = strlen("\r\n"); // 2 bytes, excluding the trailing '\0'
int sizeBitB6 = strlen(bt); // 2 bytes, excluding the trailing '\0'

sizeof returns the size of the datatype (at compile-time). But you're probably interested in the length of the string. For that purpose, you should use strlen.

Related

strncpy functions produces wrong file names

I am new in C and writing a code to help my data analysis. Part of it opens predetermined files.
This piece of code is giving me problems and I cannot understand why.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAXLOGGERS 26
// Declare the input files
char inputfile[];
char inputfile_hum[MAXLOGGERS][8];
// Declare the output files
char newfile[];
char newfile_hum[MAXLOGGERS][8];
int main()
{
int n = 2;
while (n > MAXLOGGERS)
{
printf("n error, n must be < %d: ", MAXLOGGERS);
scanf("%d", &n);
}
// Initialize the input and output file names
strncpy(inputfile_hum[1], "Ahum.csv", 8);
strncpy(inputfile_hum[2], "Bhum.csv", 8);
strncpy(newfile_hum[1], "Ahum.txt", 8);
strncpy(newfile_hum[2], "Bhum.txt", 8);
for (int i = 1; i < n + 1; i++)
{
strncpy(inputfile, inputfile_hum[i], 8);
FILE* file1 = fopen(inputfile, "r");
// Safety check
while (file1 == NULL)
{
printf("\nError: %s == NULL\n", inputfile);
printf("\nPress enter to exit:");
getchar();
return 0;
}
strncpy(newfile, newfile_hum[i], 8);
FILE* file2 = fopen(newfile, "w");
// Safety check
if (file2 == NULL)
{
printf("Error: file2 == NULL\n");
getchar();
return 0;
}
for (int c = fgetc(file1); c != EOF; c = fgetc(file1))
{
fprintf(file2, "%c", c);
}
fclose(file1);
fclose(file2);
}
// system("Ahum.txt");
// system("Bhum.txt");
}
This code produces two files but instead of the names:
Ahum.txt
Bhum.txt
the files are named:
Ahum.txtv
Bhum.txtv
The reason I am using strncpy in the for loop is because n will actually be inputted by the user later.
I see at least three problems here.
The first problem is that your character array is too small for your strings.
"ahum.txt", etc. will need to take nine characters. Eight for the actual text plus one more for the null terminating character.
The second problem is that you have declared the character arrays "newfile" and "inputfile" as empty arrays. These also need to be a number able to contain the strings (at least 9).
You're lucky to have not had a crash from overwriting memory out the program space.
The third and final problem is your use of strcpy().
strncpy(dest, src, n) will copy n characters from src to dest, but it won't copy final null terminator character if n is equal or less than size of the src string.
From strncpy() manpage: https://linux.die.net/man/3/strncpy
The strncpy() function ... at most n bytes of src are copied.
Warning: If there is no null byte among the first n bytes of src,
the string placed in dest will not be null-terminated.
Normally what you would want to do is have "n" be the size of the destination buffer minus 1 to allow for the null character.
For example:
strncpy(dest, src, sizeof(dest) - 1); // assuming dest is char array
There are a couple of problems with your code.
inputfile_hum, newfile_hum, need to be to be one char bigger for the trailing '\0' on strings.
char inputfile_hum[MAXLOGGERS][9];
...
char newfile_hum[MAXLOGGERS][9];
strncpy expects the first argument to be a char * region big enough to hold the expected results, so inputfile[] and outputfile[] need to be declared:
char inputfile[9];
char outputfile[9];

Encoding dec char instead of octal

I do not understand why
char test = '\032';
converts to
26 dec
'\032' seems to be interpreted as octal, but I want it to be treated as a decimal number.
I think I am confused with the character encoding.
Can anybody clarify this for me and give me a hint on how to convert it the way I want it?
In C, '\octal-digit' begins an octal-escape-sequence. There is no decimal-escape-sequence.
Code could simply use:
char test = 32;
To assign the value of 32 to a char, code has many options:
// octal escape sequence
char test1 = '\040'; // \ and then 1, 2 or 3 octal digits
char test2 = '\40';
// hexadecimal escape sequence
char test3 = '\x20'; // \x and then 1 or more hexadecimal digits
// integer decimal constant
char test4 = 32; // 1-9 and then 0 or more decimal digits
// integer octal constant
char test5 = 040; // 0 and then 0 or more octal digits
char test6 = 0040;
char test7 = 00040;
// integer hexadecimal constant
char test8 = 0x20; // 0x or 0X and then 1 or more hexadecimal digits
char test9 = 0X20;
// universal-character-name
char testA = '\u0020'; // \u & 4 hex digits
char testB = '\U00000020'; // \U & 8 hex digits
// character constant
char testC = ' '; // When the character set is ASCII
The syntax you are using (\0xxx) is for octal. To use decimal, you can just do:
char test = (char)32;

How to calculate CheckSum in FIX manually?

I have a FixMessage and I want to calculate the checksum manually.
8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
The body length here is calculated:
8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
0 + 0 + 5 + 5 + 8 + 26 + 5 + 0 = 49(correct)
The checksum is 157 (10=157). How to calculate it in this case?
You need to sum every byte in the message up to but not including the checksum field. Then take this number modulo 256, and print it as a number of 3 characters with leading zeroes (e.g. checksum=13 would become 013).
Link from the FIX wiki: FIX checksum
An example implementation in C, taken from onixs.biz:
char *GenerateCheckSum( char *buf, long bufLen )
{
static char tmpBuf[ 4 ];
long idx;
unsigned int cks;
for( idx = 0L, cks = 0; idx < bufLen; cks += (unsigned int)buf[ idx++ ] );
sprintf( tmpBuf, "%03d", (unsigned int)( cks % 256 ) );
return( tmpBuf );
}
Ready-to-run C example adapted from here
8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|10=157|
#include <stdio.h>
void GenerateCheckSum( char *buf, long bufLen )
{
unsigned sum = 0;
long i;
for( i = 0L; i < bufLen; i++ )
{
unsigned val = (unsigned)buf[i];
sum += val;
printf("Char: %02c Val: %3u\n", buf[i], val); // print value of each byte
}
printf("CheckSum = %03d\n", (unsigned)( sum % 256 ) ); // print result
}
int main()
{
char msg[] = "8=FIX.4.2\0019=49\00135=5\00134=1\00149=ARCA\00152=20150916-04:14:05.306\00156=TW\001";
int len = sizeof(msg) / sizeof(msg[0]);
GenerateCheckSum(msg, len);
}
Points to Note
GenerateCheckSum takes the entire FIX message except CheckSum field
Delimiter SOH is written as \001 which has ASCII value 1
static void Main(string[] args)
{
//10=157
string s = "8=FIX.4.2|9=49|35=5|34=1|49=ARCA|52=20150916-04:14:05.306|56=TW|";
byte[] bs = GetBytes(s);
int sum=0;
foreach (byte b in bs)
sum = sum + b;
int checksum = sum % 256;
}
//string to byte[]
static byte[] GetBytes(string str)
{
byte[] bytes = new byte[str.Length * sizeof(char)];
System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
return bytes;
}
Using BodyLength[9] and CheckSum[10] fields.
BodyLength is calculated starting from field starting after BodyLenght and
before CheckSum field.
CheckSum is calculated from ‘8= upto SOH before the checksum field.
Binary value of each character is calculated and compared to the LSB of the calculated value to the checksum value.
If the checksum has been calculated to be 274 then the modulo 256 value is 18 (256 + 18 = 274). This value would be transmitted a 10=018 where
"10="is the tag for the checksum field.
In Java there is a method from QuickFixJ.
String fixStringMessage = "8=FIX.4.29=12535=81=6090706=011=014=017=020=322=837=038=4.39=054=155=ALFAA99=20220829150=0151=06020=06021=06022=F9014=Y";
int checkSum = quickfix.MessageUtils.checksum(fixStringMessage);
System.out.prinln(checkSum);
Output: 127
Hope it can help you.

Converting a character array of packed decimal to integer in C program

I need to write a C program to convert packed decimal field in a buffer to in integer value. The precision of packed decimal is 9 and Scale is 0. What is the best way to convert this in a IBM mainframe C progrram? In Cobol the format for Packed Decimal used is Comp-3
Any help is aprreciated.
If you are running the program on a Zos mainframe then the C compiler supports packed decimal natively.
Google for "Zos C fixed point decimal type" should get you the right manual page
its a simple as :
#include <decimal.h>
decimal(9,0) mynum;
The one way I think it can be done, is
long long MyGetPackedDecimalValue(char* pdIn, int length)
{
// Convert packed decimal to long
const int PlusSign = 0x0C; // Plus sign
const int MinusSign = 0x0D; // Minus `enter code here`
const int NoSign = 0x0F; // Unsigned
const int DropHO = 0xFF; // AND mask to drop HO sign bits
const int GetLO = 0x0F; // Get only LO digit
long long val = 0; // Value to return
printf ("in side ****GetPDVal \n ");
for(int i=0; i < length; i++)
{
int aByte = pdIn[i] & DropHO; // Get next 2 digits & drop sign bits
if(i == length - 1)
{ // last digit?
int digit = aByte >> 4; // First get digit
val = val*10 + digit;
printf("digit= %d, val= %lld \n",
digit,
val);
int sign = aByte & GetLO; // now get sign
if (sign == MinusSign)
{
val = -val;
}
else
{
// Do we care if there is an invalid sign?
if(sign != PlusSign && sign != NoSign)
perror("SSN:Invalid Sign nibble in Packed Decimal\n");
}
}
else
{
int digit = aByte >> 4; // HO first
val = val*10 + digit;
printf("digit= %d, val= %lld \n",
digit,
val);
digit = aByte & GetLO; // now LO
val = val*10 + digit;
printf("digit= %d, val= %lld \n",
digit,
val);
}
}`enter code here`
printf ("**** coming out GetPDVal \n ");
return val;
}

Formatting a (large) number "12345" to "12,345"

Say I have a large number (integer or float) like 12345 and I want it to look like 12,345.
How would I accomplish that?
I'm trying to do this for an iPhone app, so something in Objective-C or C would be nice.
Here is the answer.
NSNumber* number = [NSNumber numberWithDouble:10000000];
NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
[numberFormatter setNumberStyle:kCFNumberFormatterDecimalStyle];
[numberFormatter setGroupingSeparator:#","];
NSString* commaString = [numberFormatter stringForObjectValue:number];
[numberFormatter release];
NSLog(#"%# -> %#", number, commaString);
Try using an NSNumberFormatter.
This should allow you to handle this correctly on an iPhone. Make sure you use the 10.4+ style, though. From that page:
"iPhone OS: The v10.0 compatibility mode is not available on iPhone OS—only the 10.4 mode is available."
At least on Mac OS X, you can just use the "'" string formatter with printf(3).
$ man 3 printf
`'' Decimal conversions (d, u, or i) or the integral portion
of a floating point conversion (f or F) should be
grouped and separated by thousands using the non-mone-
tary separator returned by localeconv(3).
as in printf("%'6d",1000000);
Cleaner C code
// write integer value in ASCII into buf of size bufSize, inserting commas at tousands
// character string in buf is terminated by 0.
// return length of character string or bufSize+1 if buf is too small.
size_t int2str( char *buf, size_t bufSize, int val )
{
char *p;
size_t len, neg;
// handle easy case of value 0 first
if( val == 0 )
{
a[0] = '0';
a[1] = '\0';
return 1;
}
// extract sign of value and set val to absolute value
if( val < 0 )
{
val = -val;
neg = 1;
}
else
neg = 0;
// initialize encoding
p = buf + bufSize;
*--p = '\0';
len = 1;
// while the buffer is not yet full
while( len < bufSize )
{
// put front next digit
*--p = '0' + val % 10;
val /= 10;
++len;
// if the value has become 0 we are done
if( val == 0 )
break;
// increment length and if it's a multiple of 3 put front a comma
if( (len % 3) == 0 )
*--p = ',';
}
// if buffer is too small return bufSize +1
if( len == bufSize && (val > 0 || neg == 1) )
return bufSize + 1;
// add negative sign if required
if( neg == 1 )
{
*--p = '-';
++len;
}
// move string to front of buffer if required
if( p != buf )
while( *buf++ = *p++ );
// return encoded string length not including \0
return len-1;
}
I did this for an iPhone game recently. I was using the built-in LCD font, which is a monospaced font. I formatted the numbers, ignoring the commas, then stuck the commas in afterward. (The way calculators do it, where the comma is not considered a character.)
Check out the screenshots at RetroJuJu. Sorry--they aren't full-sized screenshots so you'll have to squint!
Hope that helps you (it's in C) :
char* intToFormat(int a)
{
int nb = 0;
int i = 1;
char* res;
res = (char*)malloc(12*sizeof(char));
// Should be enough to get you in the billions. Get it higher if you need
// to use bigger numbers.
while(a > 0)
{
if( nb > 3 && nb%3 == 0)
res[nb++] = ',';
// Get the code for the '0' char and add it the position of the
// number to add (ex: '0' + 5 = '5')
res[nb] = '0' + a%10;
nb++;
a /= 10;
}
reverse(&res);
return res;
}
There might be a few errors I didn't see (I'm blind when it comes to this...)
It's like an enhanced iToA so maybe it's not the best solution.
Use recursion, Luke:
#include <stdio.h>
#include <stdlib.h>
static int sprint64u( char* buffer, unsigned __int64 x) {
unsigned __int64 quot = x / 1000;
int chars_written;
if ( quot != 0) {
chars_written = sprint64u( buffer, quot);
chars_written += sprintf( buffer + chars_written, ".%03u", ( unsigned int)( x % 1000));
}
else {
chars_written = sprintf( buffer, "%u", ( unsigned int)( x % 1000));
}
return chars_written;
}
int main( void) {
char buffer[ 32];
sprint64u( buffer, 0x100000000ULL);
puts( buffer);
return EXIT_SUCCESS;
}