Sliced string and char buffer are not equal - c

I want to extract the packet number from the received message and want to compare with originally sent packet_count and trying with following code
char string[] = "Hello client 0000!";
char new[4];
char bufNew[4];
int i=0;
int count=0;
int num=0;
int packet_counter=0;
for (i=13;i<17;i++)
{
new[count] = string[i];
count = count+1;
}
new[4]='\0';
printf("Sliced no is: %s\n",new);
sprintf(bufNew, "%04d", packet_counter);
bufNew[4]='\0';
printf("packet counter is: %s\n",bufNew);
printf("String compare result: %d\n",strcmp(new,bufNew));
Although the output look same, strings are different.
Output:
Sliced no is: 0000
packet counter is: 0000
String compare result: 48
Please guide how to make both these strings equal.

It is likely that sprintf(bufNew, "%04d", packet_counter); overwrites the terminating 0 of new (since as others said, it is used out of its bounds). Try moving the printf("Sliced no is: %s\n",new); down below bufNew[4]='\0'; to see it for yourself.
To fix it, newand bufNew needs to be declared with size 5:
char new[5];
char bufNew[5];

Related

C programming copying an array of char to a 2d array of char

In this part of the project I'm trying to copy an array of char that has spaces into a 2D array of char where I want to separate each string in the 1D array before spaces and put it into the 2D array of char.
This is my code.
#include <stdio.h>
int main()
{
int tracker = 0;
char string[100];
int b1 = 0;
int b2 = 0;
char bitString[100][8];
printf("Project Zero\n");
printf("Enter an 8-bit Binary Number!\n");
gets(string);
memset(&bitString[0], 0, sizeof(bitString));
while(string[tracker] != '\0')
{
if(!isspace(string[tracker]))
{
bitString[b1][b2] = *(string+tracker);
b2++;
tracker++;
}
else
{
b1++;
tracker++;
b2=0;
}
}
printf("String is: %s\n",*(bitString+0));
printf("String is: %s\n",*(bitString+1));
return 0;
}
My input is this: 00001111 00001100
The result is this:
String is: 0000111100001100
String is: 00001100
I don't understand why the result for *(bitString+0) is all of the strings I entered without space.
Can someone please explain to me why this is happening and what can I do to fix it.
If you change char bitString[100][8]; to char bitString[100][9]; it works.
I think that the C compiler automatically places the null char at the end of the row of every char array to know that the string ends there, when you write to the 7th position of bitString in one of its rows you replace the null char with a pointer to the rest of the char array string where the program stores the user input, so when you print it, it just keeps going until it finds the null char of string.
And you should include the libraries <ctype.h> and <string.h> to support all of the functions you use.
If the variable b2, in the while loop, is bigger than size of j parameter in char bitString[i][j]; induce to segmentation fault in the bitString[0][8] interaction.

How do I return a string of hex in C?

I have a cryptographic program in which I need to represent each character by its hex value and return all of these hex values as a char string. After multiple crypto functions I got a final decimal value of each char. Now at the end of a for cycle I need to put all of them in a string containing each character hex value separated by space. In short, I have decimal number, which I need to convert to hex and put them in a string for return. Thanks for responses. I tried sprintf() but I obviously can't put it into char string because it can only hold one char per index. I am a university student and its my first year working with C so please keep that in mind. I hope it is not such noob question.
I tried something.
at the top before loop starts I wrote this:
char*res=calloc(size,sizeof(unsigned char));
and before the end of loop i wrote this:
sprintf(&res[i],"%02x",dec);
dec - decimal value of a character. if i print it out i get the right output.
now my output should be "80 9c 95 95 96 11 bc 96 b9 95 9d 10"
but instead I got "899991b9b9910".
it means i got only 1st character of each hex value except the last one. im sure now you might get a solution for me. THANK YOU!
I figured it out:
char*res = calloc(size,sizeof(unsigned char)*3);
sprintf(&res[f*3],"%x ", dec);
When I return and print res, it prints out as I wanted. Please, if you can, modify this answer for others to understand. Thank you all for help!
char * getString(unsigned char *s,int len)
{
char *res=calloc(sizeof(unsigned char),len*3+1);
for(int i=0;i<len;++i)
{
sprintf(&res[i*3],"%x ",s[i]);
}
return res;
}
Will this help?
Usage:
unsigned char [] data= {'H' ,'E' , 'L', 'l', 'o'};
char* str=getString(data,sizeof(data)/sizeof(unsigned char));
printf("%s",str);
free(str);
Or:
int main()
{
unsigned char input[20] ={0,};
scanf("%19s",input);
encrypt(input,strlen(input));
char* str=getString(data,sizeof(data)/sizeof(unsigned char));
printf("%s",str);
free(str);
return 0;
}
And the void encrypt(unsigned char *input, int len) modifies the input array.
I think converting the data at once is easier to implement.
Also you need to #include
<stdio.h>, <stdlib.h>.
this code may add additional space at end of the line of string generated...
And this post can answer you or your question is duplicate if I got your point.
And seeing that post, I'll have to practice C skills a lot.. I'm a student either so have more time to learn..
edit
Or To fit your need(?):
char * getString(unsigned char *s,int len)
{
char *res=calloc(sizeof(unsigned char),len*3+1);
for(int i=0;i<len;++i)
{
s[i]=your_process(s[i]);
sprintf(&res[i*3],"%x ",s[i]);
}
return res;
}

Converting massive binary input string into character string C

I'm not familiar with C at all so this might be a simple problem to solve. I'm trying to take an input char* array of binary character sequences, ex. "0100100001101001", and output its relative string ("Hi"). The problem I'm having is coming up with a way to split the input into seperate strings of length 8 and then convert them individually to ulimately get the full output string.
char* binaryToString(char* b){
char binary[8];
for(int i=0; i<8; ++i){
binary[i] = b[i];
}
printf("%s", binary);
}
I'm aware of how to convert 8-bit into its character, I just need a way to split the input string in a way that will allow me to convert massive inputs of 8-bit binary characters.
Any help is appreciated... thanks!
From what I can tell, your binaryToString() function does not do what you'd want it to. The print statement just prints the first eight characters from the address pointed to by char* b.
Instead, you can convert the string of 8 bits to an integer, utilizing a standard C function strtol(). There's no need to convert any further, because binary, hex, decimal, etc, are all just representations of the same data! So once the string is converted to a long, you can use that value to represent an ASCII character.
Updating the implementation (as below), you can then leverage it to print a whole sequence.
#include <stdio.h>
#include <string.h>
void binaryToString(char* input, char* output){
char binary[9] = {0}; // initialize string to 0's
// copy 8 bits from input string
for (int i = 0; i < 8; i ++){
binary[i] = input[i];
}
*output = strtol(binary,NULL,2); // convert the byte to a long, using base 2
}
int main()
{
char inputStr[] = "01100001011100110110010001100110"; // "asdf" in ascii
char outputStr[20] = {0}; // initialize string to 0's
size_t iterations = strlen(inputStr) / 8; // get the # of bytes
// convert each byte into an ascii value
for (int i = 0; i < iterations; i++){
binaryToString(&inputStr[i*8], &outputStr[i]);
}
printf("%s", outputStr); // print the resulting string
return 0;
}
I compiled this and it seems to work fine. Of course, this can be done cleaner and safer, but this should help you get started.
I just need a way to split the input string in a way that will allow me to convert massive inputs of 8-bit binary characters.
You can use strncpy() to copy the sequence of '0' and '1' in a chunk of 8 characters at a time from the input string, something like this:
//get the size of input string
size_t len = strlen(b);
//Your input array of '0' and '1' and every sequence of 8 bytes represents a character
unsigned int num_chars = len/8;
//Take a temporary pointer and point it to input string
const char *tmp = b;
//Now copy the 8 chars from input string to buffer "binary"
for(int i=0; i<num_chars; ++i){
strncpy(binary, tmp+(i*8), 8);
//do your stuff with the 8 chars copied from input string to "binary" buffer
}
Maybe this can help. I didnt compile it but there is the idea. You can loop every 8 bit separately with while loop. And assign 8 bit to binary array with for loop. After that send this binary array to convert8BitToChar function to get letter equivalent of 8 bit. Then append the letter to result array. I'm not writing c for 3 year if there is mistakes sorry about that. Here pseudo code.
char* binaryToString(char* b){
char* result = malloc(sizeof(256*char));
char binary[8];
int nextLetter = 0;
while (b[nextLetter*8] != NULL) { // loop every 8 bit
for(int i=0; i<8; ++i){
binary[i] = b[nextLetter*8+i];
}
result[nextLetter] = 8bitToChar(binary));// convert 8bitToChar and append yo result
nextLetter++;
}
result[nextLetter] = '\0';
return result;
}

Cast an int array to string, then print with printf, without allocating new memory

I thought I had this solved, but apparently, I was incorrect. The question is... what did I miss?
Assignment description:
You are to create a C program which fills an integer array with integers and then you are to cast it as a string and print it out. The output of the string should be your first and last name with proper capitalization, spacing and punctuation. Your program should have structure similar to:
main()
{
int A[100];
char *S;
A[0]=XXXX;
A[1]=YYYY;
...
A[n]=0; -- because C strings are terminated with NULL
...
printf("My name is %s\n",S);
}
Response to my submission:
You still copied memory cells to other, which is not expected. You use different space for the integer array as the string which does not follow the requirements. Please follow the instructions carefully next time.
My submission
Note that the first time I submitted, I simply used malloc on S, and copied casted values from A to S. The response was that I could not use malloc or allocate new space. This requirement was not in the problem description above.
Below was my second and final submission, which is the submission being referred to in the submission response above.
#include <stdio.h>
/* Main Program*/
int main (int arga, char **argb){
int A[100];
char *S;
A[0] = 68;
A[1] = 117;
/** etc. etc. etc. **/
A[13] = 115;
A[14] = 0;
// Point a char pointer to the first integer
S = (char *) A;
// For generality, in C, [charSize == 1 <= intSize]
// This is the ratio of intSize over charSize
int ratio = sizeof(int);
// Copy the i'th (char sized) set of bytes into
// consecutive locations in memory.
int i = 0;
// Using the char pointer as our reference, each set of
// bits is then i*ratio positions away from the i'th
// consecutive position in which it belongs for a string.
while (S[i*ratio] != 0){
S[i] = S[i*ratio];
i++;
}
// a sentinel for the 'S string'
S[i] = 0;
printf("My name is %s\n", S);
return 0;
}// end main
It looks like you've got the core idea down: the space for one integer will hold many chars. I believe you just need to pack the integer array "by hand" instead of in the for loop. Assuming a 4-byte integer on a little-endian machine, give this a shot.
#include <stdio.h>
int main()
{
int x[50];
x[0] = 'D' | 'u' << 8 | 's' << 16 | 't' << 24;
x[1] = 0;
char *s = (char*)x;
printf("Name: %s\n", s);
return 0;
}
It sounds like your professor wanted you to put 4 bytes into each int instead of having an array of n "1 byte" ints that you later condensed into 4 / sizeof(int) bytes using the while loop. Per Hurkyl's comment, the solution to this assignment would be platform dependent, meaning that it will differ from machine to machine. I'm assuming your instructor had the class ssh into and use a specific machine?
In any case, assuming you're on a little endian machine, say you wanted to type out the string: "Hi Dad!". Then a snippet of the solution would look something like this:
// Precursor stuff
A[0] = 0x44206948; // Hi D
A[1] = 0x216461; // ad!
A[2] = 0; // Null terminated
char *S = (char *)A;
printf("My string: %s\n", S);
// Other stuff

Convert byte array / char array to hexidecimal string in C

I think my understanding of bytes arrays and char arrays is causing me some issues, here is my problem:
I have an application that pulls messages from Websphere MQ and sends them onto a target system.
A MQ message has a MQBYTE24 (byte array 24 essentially) that represents the MSGID of the message. My goal is to convert this to a hexidecimal string.
On the WMQ explorer on my Linux box message 1 in the queue has a message identifier of "AMQ QM01" (at least that it what it looks like), and the bytes are below as displayed in the explorer:
00000 41 4D 51 20 51 4D 30 31--20 20 20 20 20 20 20 20 |AMQ QM01 |
00010 BD F4 A8 4E A2 A3 06 20-- |...N... |
Now when my code runs I pick up that same message id and try convert it to a hex string.
The exact message id while debugging is:
AMQ QM01 \275\364\250N\242\243\006
And after running through my conversion (code below) i get:
414D5120514D30312020202020202020FFFFFF4EFFFF6
As you can see it is slightly different to the one that the WMQ Explorer shows, any idea what i am doing wrong here?
I assume it is me converting from the MQBYTE24 to char....something is going wrong there...
Below is a small sample program that produces the "wrong result".....i assune i must use a byte array instead of char?
The output for the following is:
Result: 414D5120514D30312020202020202020FFFFFF4EFFFF6
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(){
char name[41]="AMQ QM01 \275\364\250N\242\243\006";
char buffer[82]="";
char *pbuffer = buffer;
FILE *fp_1;
FILE *fp_2;
int size;
char *buffer_1 = NULL;
char *buffer_2 = NULL;
int rc = convertStrToHex(buffer, name);
printf( "Result: %s\n", pbuffer );
}
return 0;
}
int convertStrToHex(char *buffer, char str[10]){
int len = strlen(str);
int i;
for( i = 0; i < len ;i++ ){
sprintf(buffer, "%X", str[i]);
buffer +=2;
};
}
Thanks for the help :-)
Lynton
Depending on the compiler and platform char is signed or not and printf's behaviour is different.
Just cast str[i] to unsigned char (or change the type of str in the function's prototype) and it will work. For example (prototype changed):
int convertStrToHex(char *buffer, unsigned char str[10]){
int len = strlen(str);
int i;
for( i = 0; i < len ;i++ ){
sprintf(buffer, "%X", str[i]);
buffer +=2;
};
}
BTW: it considered as unsafe to pass a string without it's allocated length and to use sprintf. You should use snprintf with the real length of buffer or at least handle the size limit yourself inside the loop. In case strlen(str) is larger than buffer's size * 2.
As several other answers already point out, you need to cast the characters to unsigned char to avoid their being padded with FF to fill a 32-bit int's worth of bytes. But there's actually another issue: that lone number 6 at the end will only print as one character in the output. You want each character to take up exactly two positions, so you need a zero-padded field specifier. Putting it all together, you get
sprintf(buffer, "%02X", (unsigned char)str[i]);
Try
sprintf(buffer, "%X", (unsigned char)str[i]);

Resources