I am trying to find the height and width of jpg/jpeg image in c language.
I have seen some lines of code
iPos = iPos + 5;
*ipHeight = ucpImageBuffer[iPos]<<8|ucpImageBuffer[iPos+1];
*ipWidth = ucpImageBuffer[iPos+2]<<8|ucpImageBuffer[iPos+3];
printf("\nW x H = %d x %d\n\n",*ipWidth,*ipHeight);
I find some lines of code as shown above but I don't know what should be in ucpImageBuffer?
And i also don't know from where I have to start?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void main()
{
int iHeight=0, iWidth=0, iPos, i;
char *cpFileName = "/images/image1.jpg";
FILE *fp = fopen(cpFileName,"rb");
fseek(fp,0,SEEK_END);
long len = ftell(fp);
fseek(fp,0,SEEK_SET);
unsigned char *ucpImageBuffer = (unsigned char*) malloc (len+1);
fread(ucpImageBuffer,1,len,fp);
fclose(fp);
printf("\n\nBuffer size %ld", len);
/*Extract start of frame marker(FFCO) of width and hight and get the position*/
for(i=0;i<len;i++)
{
if((ucpImageBuffer[i]==0xFF) && (ucpImageBuffer[i+1]==0xC0) )
{
iPos=i;
break;
}
}
/*Moving to the particular byte position and assign byte value to pointer variable*/
iPos = iPos + 5;
iHeight = ucpImageBuffer[iPos]<<8|ucpImageBuffer[iPos+1];
iWidth = ucpImageBuffer[iPos+2]<<8|ucpImageBuffer[iPos+3];
printf("\nWxH = %dx%d\n\n", iWidth, iHeight);
free(ucpImageBuffer);
}
Related
I started learning C language about 1 week, and I'm trying to build my first programs. I'm coming from Python, so the C syntax isn't very clear for me, and I haven't understand the solutions that I found online.
So, if I have this string:
char str[50] = "dimension[1080,720];"
and i want to create two integer variables that containes 1080 and 720 and string var that contains the first string. But these two numbers can change, and they can have random cifras. So, i wanted my output is
int x = 1080
int y = 720
*the values are always two, but the lenght can change.
How can i do that?
Second version:
So, if I have this string:
char str[50] = "dimension["string",1080,720];"
and i want to create two integer variables that containes 1080 and 720 and string var that contains the first string. But these two numbers can change, and they can have random cifras. So, i wanted my output is
char str[1000] = "string";
int x = 1080
int y = 720
the values are always three, but the lenght can change.
How can i do that?
use sscanf function
int main(void)
{
char str[] = "dimension[1080,720];";
int x,y;
if(sscanf(str, "dimension[%d,%d", &x, &y) != 2) {printf("Error\n");}
else printf("X=%d Y=%d", x, y);
}
Question two:
int main(void)
{
char str[] = "dimension[\"string\",1080,720];";
char str1[20];
int x,y;
char *ptr = strstr(str, "[");
char *ptr1;
size_t len;
memcpy(str1, ptr + 2, len = (ptr1 = strchr(ptr + 2, '"')) - (ptr + 2));
str[len] = 0;
if(sscanf(ptr1 + 2, "%d,%d", &x, &y) != 2) {printf("Error\n");}
else printf("Str = %s X=%d Y=%d", str1, x, y);
}
The sscanf answer is perfect, but not very flexible. I add this in case you want more flexibility to parse strings. You can do it with regular expressions and in your case would be something like:
Piece of code taken from https://gist.github.com/ianmackinnon/3294587
I have added some modification to extract the numbers to the variables
#include <stdio.h>
#include <string.h>
#include <regex.h>
#include <stdlib.h>
int main ()
{
// Define regexp and input
char * source = "dimension[\"string\",1080,720];";
char * regexString = "[a-z]+\\[\"([a-z]+)\",([0-9]+),([0-9]+)\\]";
size_t maxMatches = 3;
size_t maxGroups = 4;
// Variables we want to extract from the input
char* str;
int n1;
int n2;
regex_t regexCompiled;
regmatch_t groupArray[maxGroups];
unsigned int m;
char * cursor;
if (regcomp(®exCompiled, regexString, REG_EXTENDED))
{
printf("Could not compile regular expression.\n");
return 1;
};
m = 0;
cursor = source;
for (m = 0; m < maxMatches; m ++)
{
if (regexec(®exCompiled, cursor, maxGroups, groupArray, 0))
break; // No more matches
unsigned int g = 0;
unsigned int offset = 0;
for (g = 0; g < maxGroups; g++)
{
if (groupArray[g].rm_so == (size_t)-1)
break; // No more groups
if (g == 0)
offset = groupArray[g].rm_eo;
char cursorCopy[strlen(cursor) + 1];
strcpy(cursorCopy, cursor);
cursorCopy[groupArray[g].rm_eo] = 0;
printf("Match %u, Group %u: [%2u-%2u]: %s\n",
m, g, groupArray[g].rm_so, groupArray[g].rm_eo,
cursorCopy + groupArray[g].rm_so);
switch (g)
{
case 1:
// Copy to the string now that we know the length
str = malloc(strlen(cursor)+1);
strcpy(str,cursorCopy + groupArray[g].rm_so);
break;
case 2:
n1 = (int) strtol(cursorCopy + groupArray[g].rm_so, (char **)NULL, 10); //(cursorCopy + groupArray[g].rm_so,10);
break;
case 3:
n2 = (int) strtol(cursorCopy + groupArray[g].rm_so, (char **)NULL, 10); //(cursorCopy + groupArray[g].rm_so,10);
break;
}
}
cursor += offset;
}
regfree(®exCompiled);
printf("Matches in variables: %s - %d - %d \n",str,n1,n2);
return 0;
}
This for me prints
Match 0, Group 0: [ 0-28]: dimension["string",1080,720]
Match 0, Group 1: [11-17]: string
Match 0, Group 2: [19-23]: 1080
Match 0, Group 3: [24-27]: 720
Matches in variables: string - 1080 - 720
I want to use C language to implement the recognition of mnist datasets, using a backpropagation algorithm, but when loading the input layer neural units, the Segmentation fault (core dumped) is displayed, here's the code snippet, why, and how to solve it.
#include <stdio.h>
#include <unistd.h>
#include <math.h>
#include <stdlib.h>
#include <time.h>
#define PATH_TRAIN_IMAGES "../../train-images-idx3-ubyte"
#define PATH_TRAIN_LABELS "../../train-labels-idx1-ubyte"
#define PATH_WEIGHT_DATA2 "../data/data2.weight"
#define PATH_WEIGHT_DATA3 "../data/data3.weight"
#define PATH_BIAS_DATA2 "../data/data2.bias"
#define PATH_BIAS_DATA3 "../data/data3.bias"
#define TRAIN_IMAGES_NUMBER 60000
#define PIXEL 784
#define HIDDEN_UNITS_NUMBER 300
#define OUT_UNITS_NUMBER 10
#define TRAIN_TEST 0
struct Unit
{
// input with weight
float z;
// bias
float b;
// output
float a;
};
float sigmod(float z)
{
return (1 / (1 + exp(-z)));
}
struct Unit* create_unit(float uz, float ub, float ua)
{
struct Unit* unit = (struct Unit*)malloc(sizeof(struct Unit));
unit->z = uz;
unit->b = ub;
unit->a = ua;
return unit;
}
int load_train_labels(char* path_train_labels, unsigned char* ar_label)
{
FILE *fp_label;
int size_label = 0;
fp_label = fopen(path_train_labels, "rb");
fseek(fp_label, 0, SEEK_END);
size_label = ftell(fp_label);
printf("%s size:%d byte\n", path_train_labels, size_label);
rewind(fp_label);
// Starting with the 9th byte
fseek(fp_label,8,SEEK_SET);
unsigned char train_labels_buffer[size_label];
ar_label = (unsigned char*)malloc(sizeof(unsigned char) * size_label - 8);
fread(ar_label, 1, size_label - 8, fp_label);
fclose(fp_label);
return size_label;
}
int load_train_images(char* path_train_images, unsigned char* ar_img)
{
FILE *fp_img;
int size_img = 0;
fp_img = fopen(path_train_images, "rb");
fseek(fp_img, 0, SEEK_END);
size_img = ftell(fp_img);
printf("%s size:%d byte\n", path_train_images, size_img);
rewind(fp_img);
// Starting with the 17th byte, each byte stores the value of one pixel in a picture
fseek(fp_img, 16, SEEK_SET);
ar_img = (unsigned char*)malloc(sizeof(char) * size_img - 16);
fread(ar_img, 1, size_img - 16, fp_img);
fclose(fp_img);
return size_img;
}
int load_data(char* path_data, unsigned char* ar_data)
{
FILE *fp_data;
int size_data;
fp_data = fopen(path_data, "rb");
fseek(fp_data, 0, SEEK_END);
size_data = ftell(fp_data);
fseek(fp_data, 0, SEEK_SET);
ar_data = (unsigned char*)malloc(sizeof(char) * size_data);
printf("%s size:%d byte\n", path_data, size_data);
return size_data;
}
int main(int argc, char *argv[])
{
printf("Loading train labels file.\n");
unsigned char* ar_label;
int size_label;
size_label = load_train_labels(PATH_TRAIN_LABELS, ar_label);
printf("Loading train images file.\n");
unsigned char* ar_img;
int size_img;
size_img = load_train_images(PATH_TRAIN_IMAGES, ar_img);
printf("Loading random weight file.\n");
unsigned char* ar_weight2;
int size_weight2;
size_weight2 = load_data(PATH_WEIGHT_DATA2, ar_weight2);
unsigned char* ar_weight3;
int size_weight3;
size_weight3 = load_data(PATH_WEIGHT_DATA3, ar_weight3);
printf("Loading random bias file.\n");
unsigned char* ar_bias2;
int size_bias2;
size_bias2 = load_data(PATH_BIAS_DATA2, ar_bias2);
unsigned char* ar_bias3;
int size_bias3;
size_bias3 = load_data(PATH_BIAS_DATA3, ar_bias3);
float uz = 0;
float ub = 0;
float ua = 0;
struct Unit* out_units[OUT_UNITS_NUMBER];
for (int t = 0; t < OUT_UNITS_NUMBER; t++)
{
out_units[t] = create_unit(uz, ub, ua);
}
struct Unit* hid_units[HIDDEN_UNITS_NUMBER];
for(int i = 0; i < HIDDEN_UNITS_NUMBER; i++)
{
hid_units[i] = create_unit(uz, ub, ua);
}
struct Unit* in_units[PIXEL] = {NULL};
for(int i = 0; i < PIXEL; i++)
{
in_units[i] = create_unit(uz, ub, ua);
}
/*******************
* load C1 *
*******************/
printf("Loading train...\n");
float C[TRAIN_IMAGES_NUMBER];
for(int i = 0; i < PIXEL; i++)
{
in_units[i]->a = (float)*((ar_img+i*sizeof(char))); //segmentation fault(core dumped)
printf("in_unit[%d] = %f\n", i, in_units[i]->a);
}
for(int i = 0; i < HIDDEN_UNITS_NUMBER; i++)
{
for(int j = 0; j < PIXEL; j++)
{
hid_units[i]->z += in_units[j]->a * ((float)*(ar_weight2+((i*PIXEL+j)*sizeof(float))));
}
hid_units[i]->z += ((float)*(ar_bias2+(i*sizeof(float))));
hid_units[i]->a = sigmod(hid_units[i]->z);
}
for(int i = 0; i < OUT_UNITS_NUMBER; i++)
{
for(int j = 0; j < HIDDEN_UNITS_NUMBER; j++)
{
out_units[i]->z += hid_units[j]->a * ((float)*(ar_weight3+((i*HIDDEN_UNITS_NUMBER+j)*sizeof(float))));
}
out_units[i]->z += ((float)*(ar_bias3 + (i*sizeof(float))));
out_units[i]->a = sigmod(out_units[i]->z);
}
// free(in_units)
free(ar_label);
free(ar_img);
free(ar_weight2);
free(ar_bias2);
free(ar_weight3);
free(ar_bias3);
return 0;
}
Almost all source code was uploaded. I used the gdb debugger, but only showed Program terminated with signal SIGSEGV, Segmentation fault.And I turned on ulimit, but didn't find the core file.
Your pointer-passing is flawed. When calling a function and passing that function a pointer to something, you can alter the data the pointer is pointing to, but not the address of the pointer itself so that it is visible from the caller perspective (only in the callees perspective).
For example, one of your functions signature reads:
int load_data(char* path_data, unsigned char* ar_data)
In that function, you do a
ar_data = (unsigned char*)malloc(sizeof(char) * size_data);
This is fine, but this does not effect, that the caller of the function load_data can access this allocated memory. Instead this memory address is lost as soon as that function returns.
This means, that when you write
unsigned char* ar_label;
int size_label;
size_label = load_train_labels(PATH_TRAIN_LABELS, ar_label);
then after calling the function, ar_label still has its original (uninitialized) value. What you probably meant to do was to write the function signature as (notice the extra asterisks/ampersands in the following):
int load_data(char* path_data, unsigned char** ar_data)
Then, allocate the memory as:
*ar_data = (unsigned char*)malloc(sizeof(char) * size_data);
and use the function as:
unsigned char* ar_label;
int size_label;
size_label = load_train_labels(PATH_TRAIN_LABELS, &ar_label);
This way, you are passing a pointer to a pointer and therefore can alter the address the pointer ar_label points to in the caller. This means, that this way you store the address of the mallocated memory block in the callers pointer variable instead of in a copy of the pointer variable supplied as parameter. And you therefore are allowed to access the memory this pointer points to in the caller afterwards.
#include <stdio .h>
#include <stdlib .h>
int main(){
char text1 [N] ;
char reverse [N] ;
char* txtptr = text1 ;
char* revtxtptr = reverse ;
int N;
printf (”\n Enter any text here : ”) ;
scanf(”%s”, text1);
while(N> 0){
txtptr --;
*revtxtptr = *txtptr ;
revtxtptr++;
}
*revtxtptr = ’\0’;
printf (”The reverse text is : %s \n” , reverse) ;
return 0;
}
I want to see here output the reverse form of the input.
Something like
input:
CLEARLY
output:
YLRAELC
Could you help me to fix my fault?
Here are corrections to your code:
You have spaces before the .h> in the #include lines.
You should limit the size of the buffers.
N is not initialized.
N is not being decremented.
txtptr is not being placed at the end of the C string, but it is being decremented in the while loop.
scanf is not limited to the size of the buffer(s) minus 1.
You need to either find the size of the string using strlen or walk the string until you find '\0'. (forward direction instead)
You use the wrong double-quotes and single quotes ("smart" quotes)
Here is a safe code that will reverse the input array (not in-place):
#include <stdio.h>
#include <stdlib.h>
#define MAXSTR 255
#define STR_HELPER(x) #x
#define STR(x) STR_HELPER(x)
int main() {
char text1[MAXSTR + 1];
char revbuf[MAXSTR + 1];
char* txtptr = text1;
char* reverse = revbuf + MAXSTR;
printf("\nEnter any text here : ");
scanf("%" STR(MAXSTR) "s", text1);
*reverse = '\0';
while(*txtptr) {
*--reverse = *txtptr++;
}
printf ("The reverse text is : %s \n" , reverse) ;
return 0;
}
Here you have an example function for int array.
int *reverseINTarray(int *array, size_t size)
{
int *end, *wrk = array;
if(array && size > 1)
{
end = array + size - 1;
while(end > wrk)
{
int tmp = *wrk;
*wrk++ = *end;
*end-- = tmp;
}
}
return array;
}
or
int *reverseINTarray(const int *src, int *dest, size_t size)
{
int *wrk = dest;
if(src && dest && size)
{
wrk += size - 1;
while(size--)
{
*wrk-- = *src++;
}
}
return dest;
}
Your "swap two bytes" logic is ... simply ... wrong. Does this give you any ideas?
char temp;
temp = *chartxtptr;
*chartxtptr = *txtptr;
*txtptr = temp;
You can't "swap" any two bytes without using a temporary to hold the byte that is about to be replaced.
I have a project in which I'm supposed to take in a file via the getchar() function and convert the binary characters within it to text.
Here is the code I have, that will produce the correct ASCII number for only one at a time. I don't know how to read in an entire text file's worth of binary and convert it:
#include <stdio.h>
#include <string.h>
typedef unsigned char byte;
typedef unsigned int uint;
int strbin_to_dec(const char *);
int main(void) {
char * wbin = "01001001";
int c = 0;
printf("%s to ascii %d.\n", wbin, strbin_to_dec(wbin));
printf("The character is %c", strbin_to_dec(wbin));
return 0;
}
int strbin_to_dec(const char * str) {
uint result = 0;
for (int i = strlen(str) - 1, j = 0; i >= 0; i--, j++) {
byte k = str[i] - '0';
k <<= j;
result += k;
}
return result;
}
The above code works when I enter exactly one character's worth of binary into the variable 'wbin', but I can't format this to accept the input from getchar() because getchar gives an int type. The above code produces the result:
01001001 to ascii 73.
The character is I
The file I'm supposed to translate looks like this:
0010001001001000011011110111011100100000011011110110011001110100011001010110111000100000011010000110000101110110011001010010000001001001001000000111001101100001011010010110010000100000011101000110111100100000011110010110111101110101
011101000110100001100001011101000010000001110111011010000110010101101110001000000111100101101111011101010010000001101000011000010111011001100101001000000110010101101100011010010110110101101001011011100110000101110100011001010110010000100000011101000110100001100101001000000110100101101101011100000110111101110011011100110110100101100010011011000110010100101100
01110111011010000110000101110100011001010111011001100101011100100010000001110010011001010110110101100001011010010110111001110011001011000010000001101000011011110111011101100101011101100110010101110010001000000110100101101101011100000111001001101111011000100110000101100010011011000110010100101100
01101101011101010111001101110100001000000110001001100101001000000111010001101000011001010010000001110100011100100111010101110100011010000011111100100010
0010110101010011011010010111001000100000010000010111001001110100011010000111010101110010001000000100001101101111011011100110000101101110001000000100010001101111011110010110110001100101001011000010000001010100011010000110010100100000010100110110100101100111011011100010000001001111011001100010000001000110011011110111010101110010
This is a trivial task to perform simply by using bit shifting. Also instead of using getchar, for performance, the below uses fread.
This implementation uses minimal RAM (no use of malloc), no slow string parsing or math functions such as strlen, strtol or pow, and can handle any stream of infinite size/length, including truncated streams that are not multiples of 8 bytes.
Usage:
./a.out < data.txt > out.txt
#include <stdio.h>
int main(int argc, char * argv[])
{
unsigned char byte = 0;
int bits = 0;
for(;;)
{
char buffer[1024];
int len = fread(buffer, 1, sizeof(buffer), stdin);
// if there was a read error or EOF, stop
if (len <= 0)
break;
for(int i = 0; i < len; ++i)
{
switch(buffer[i])
{
// if a binary 1, turn on bit zero
case '1':
byte |= 1;
break;
// if a binary 0, do nothing
case '0':
break;
// if antyhing else, skip
default:
continue;
}
// incrment the counter, if we dont yet have 8 bits
// shift all the bits left by one
if (++bits < 8)
byte <<= 1;
else
{
// write out the complete byte
fwrite(&byte, 1, 1, stdout);
// reset for the next byte
bits = 0;
byte = 0;
}
}
}
// write out any remaining data if the input was not a multiple of 8 in length.
if (bits)
fwrite(&byte, 1, 1, stdout);
return 0;
}
Input:
0010001001001000011011110111011100100000011011110110011001110100011001010110111000100000011010000110000101110110011001010010000001001001001000000111001101100001011010010110010000100000011101000110111100100000011110010110111101110101
011101000110100001100001011101000010000001110111011010000110010101101110001000000111100101101111011101010010000001101000011000010111011001100101001000000110010101101100011010010110110101101001011011100110000101110100011001010110010000100000011101000110100001100101001000000110100101101101011100000110111101110011011100110110100101100010011011000110010100101100
01110111011010000110000101110100011001010111011001100101011100100010000001110010011001010110110101100001011010010110111001110011001011000010000001101000011011110111011101100101011101100110010101110010001000000110100101101101011100000111001001101111011000100110000101100010011011000110010100101100
01101101011101010111001101110100001000000110001001100101001000000111010001101000011001010010000001110100011100100111010101110100011010000011111100100010
0010110101010011011010010111001000100000010000010111001001110100011010000111010101110010001000000100001101101111011011100110000101101110001000000100010001101111011110010110110001100101001011000010000001010100011010000110010100100000010100110110100101100111011011100010000001001111011001100010000001000110011011110111010101110010
Output:
"How often have I said to youthat when you have eliminated the impossible,whatever remains, however improbable,must be the truth?"-Sir Arthur Conan Doyle, The Sign Of Four
This is a function made by me! I dont know if you use the file as a parameter of execution like: ./text.exe -f binary.txt! But I dont add entries to the program! I has defined the file by my self!
I have created a function to write to a file, but if you want to use the command like ./text.exe -f binary.txt > translatedfile.txt you can simply remove the function write_to_file! Dont forget to remove the prints that you dont want because the parameter ">" will print everything!
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void binary_to_char(char *str);
void write_to_file(char *text);
int main(void)
{
printf("Getting line from file\n");
FILE *file;
char *line = NULL;
size_t len = 0;
ssize_t stringLength;
file = fopen("binary.txt", "r");
if (file == NULL)
{
fprintf(stderr, "[ERROR]: cannot open file -- binary.txt");
perror("");
exit(1);
}
while ((stringLength = getline(&line, &len, file)) != -1)
{
printf("\n%s", line);
binary_to_char(line);
}
free(line);
fclose(file);
return 0;
}
void binary_to_char(char *str)
{
char binary[9];
char *text = malloc((strlen(str) + 1) * sizeof(char));
char c;
int pos = 0;
int letter_pos = 0;
printf("\nConverting into characters\n");
for (size_t j = 0; j < strlen(str) / 8; j++)
{
for (int i = 0; i < 8; i++)
{
binary[i] = str[pos];
pos++;
}
c = strtol(binary, 0, 2);
text[letter_pos] = c;
letter_pos++;
}
printf("\n%s\n", text);
write_to_file(text);
free(text);
}
void write_to_file(char *text)
{
printf("\nContent saved to translatedfile.txt\n");
FILE *fp;
fp = fopen("translatedfile.txt", "w+");
fprintf(fp, "%s", text);
fclose(fp);
}
Content of File binary.txt:
001000100100100001101111011101110010000001101111011001100111010001100101011011100010000001101000011000010111011001100101001000000100100100100000011100110110000101101001011001000010000001110100011011110010000001111001011011110111010101110100011010000110000101110100001000000111011101101000011001010110111000100000011110010110111101110101001000000110100001100001011101100110010100100000011001010110110001101001011011010110100101101110011000010111010001100101011001000010000001110100011010000110010100100000011010010110110101110000011011110111001101110011011010010110001001101100011001010010110001110111011010000110000101110100011001010111011001100101011100100010000001110010011001010110110101100001011010010110111001110011001011000010000001101000011011110111011101100101011101100110010101110010001000000110100101101101011100000111001001101111011000100110000101100010011011000110010100101100011011010111010101110011011101000010000001100010011001010010000001110100011010000110010100100000011101000111001001110101011101000110100000111111001000100010110101010011011010010111001000100000010000010111001001110100011010000111010101110010001000000100001101101111011011100110000101101110001000000100010001101111011110010110110001100101001011000010000001010100011010000110010100100000010100110110100101100111011011100010000001001111011001100010000001000110011011110111010101110010
Read in all the input from the file, and pass in 8 chars at a time to a converter function to return a char. Each char is 8 bits, and each character in the file represents 1 bit.
char string_to_character(char * in)
{
char ret = 0;
int i;
for(i = 7; i >= 0; i--)
if(in[i] == '1')
ret += 1 << (7 - i);
return ret;
}
This function will decode each 8 chars from the file into one character. Simply call the function with an offset of 8 chars for the entire input string and save the result somewhere.
EDIT: Be sure to include and link math library math.h.
EDIT 2: Should be >= not >
For looping...
Say you have the entire file as one long string.
int num_chars = (sizeof(input) / sizeof(char)) / 8;
int i;
char output[num_chars + 1];
for(i = 0; i < num_chars; i++)
output[i] = string_to_character(input + (i * 8));
printf("%s", output);
This was the result I got from the program
"How often have I said to youthat when you have eliminated the impossible,whatever remains, however improbable,must be the truth?"-Sir Arthur
Conan Doyle, The Sign Of Four
EDIT: left bitshift vs pow
i wanted to split this hexstring, convert em, and store em in an array.
but it seems there is something off from my work, and i don't know what.
I intend to split this string
27CA6B
to
27
CA
6B
but the output is always only the first string.
like
27
51819
0
please somebody help, here is my code
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
int main(void)
{
char bc[] = "27CA6B";
char *theEnd;
long result;
long resulta;
long resultb;
long resultc;
result = strtol (bc, &theEnd, 0);
resulta = strtol (theEnd, &theEnd, 16 );
resultb = strtol (theEnd, NULL, 0);
//int i = 0;
//printf("%c%c%c%c%c%c\n", bc[0], bc[1], bc[2], bc[3], bc[4], bc[5]);
printf("%ld\n", result, &bc[0]);
printf("%ld\n", resulta, &bc[1]);
printf("%ld\n", resultb, &bc[2]);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void){
char bc[] = "27CA6B";
unsigned char result[(sizeof(bc)-1)/2] = {0};
int i = 0;
for(char *p = bc; *p; p += 2){
char part[3] = {0};
memcpy(part, p, 2);//Extract 2 characters
result[i++] = strtoul(part, NULL, 16);
}
for(i = 0; i < sizeof(result); ++i){
printf("%3u %c%c\n", result[i], bc[i*2], bc[i*2+1]);
}
return 0;
}
expand loop
unsigned char result1,result2,result3;
int i = 0;
char part[3] = {0};
memcpy(part, bc + i, 2); i += 2;
result1 = strtoul(part, NULL, 16);
memcpy(part, bc + i, 2); i += 2;
result2 = strtoul(part, NULL, 16);
memcpy(part, bc + i, 2); i += 2;
result3 = strtoul(part, NULL, 16);
i = 0;
printf("%3u %c%c\n", result1, bc[i], bc[i+1]); i += 2;
printf("%3u %c%c\n", result2, bc[i], bc[i+1]); i += 2;
printf("%3u %c%c\n", result3, bc[i], bc[i+1]); i += 2;
The "issue" that you see in because of this line
resulta = strtol (theEnd, &theEnd, 16 );
there, theEnd points to CA6B which, as per the base 16, is a valid input as whole, so the whole string is consumed and converted. The decimal representation value is 51819, which you see as output.
The best way to achieve this would be (based on your approach) to take a pointer to the starting of the array, and "clip" it on alternate indexes.
That said, all your printf() statements are logically wrong, as you have only one format specifier but you supply two arguments, so as the last one will be ignored silently.