// Works
int fnamesize=0;
fnamesize=message[0]<<24;
fnamesize+=message[1]<<16;
fnamesize+=message[2]<<8;
fnamesize+=message[3];
// Doesn't work
int fsize;
memcpy(&fsize,message,sizeof(int));
Can someone explain why the second one doesn't work? The memory I'm copying from, message is a char *. When I try to test the values of fnamesize and fsize, like printf("fsize is %d,fnamesize is %d",fsize,fnamesize);, the fsize gives an unexpected value, but fnamesize gives the value I expect.
Thoughts?
That's because of endianess, which means the layout of bytes in an int.
In windows, the second way will give you an int that has the opposite byte order, like this:
fsize=message[3]<<24;
fsize+=message[2]<<16;
fsize+=message[1]<<8;
fsize+=message[0];
Try changing the order of the array indices in your code that works, compare the result to the code that doesn't work, and look up the terms "big endian" and "little endian".
Related
Quick question for those more experienced in c...
I want to compute a SHA256 checksum using the functions from openssl for the current time an operation takes place. My code consists of the following:
time_t cur_time = 0;
char t_ID[40];
char obuf[40];
char * timeBuf = malloc(sizeof(char) * 40 + 1);
sprintf(timeBuf, "%s", asctime(gmtime(&cur_time)));
SHA256(timeBuf, strlen(timeBuf), obuf);
sprintf(t_ID, "%02x", obuf);
And yet, when I print out the value of t_ID in a debug statement, it looks like 'de54b910'. What am I missing here?
Edited to fix my typo around malloc and also to say I expected to see the digest form of a sha256 checksum, in hex.
Since obuf is an array, printing its value causes it to decay to a pointer and prints the value of the memory address that the array is stored at. Write sensible code to print a 256-bit value.
Maybe something like:
for (int i = 0; i < 32; ++i)
printf("%02X", obuf[i]);
This is not really intended as an answer, I'm just sharing a code fragment with the OP.
To hash the binary time_t directly without converting the time to a string, you could use something like (untested):
time_t cur_time;
char t_ID[40];
char obuf[40];
gmtime(&cur_time);
SHA256(&cur_time, sizeof(cur_time), obuf);
// You know this doesn't work:
// sprintf(t_ID, "%02x", obuf);
// Instead see https://stackoverflow.com/questions/6357031/how-do-you-convert-buffer-byte-array-to-hex-string-in-c
How do you convert buffer (byte array) to hex string in C?
This doesn't address byte order. You could use network byte order functions, see:
htons() function in socket programing
http://beej.us/guide/bgnet/output/html/multipage/htonsman.html
One complication: the size of time_t is not specified, it can vary by platform. It's traditionally 32 bits, but on 64 bit machines it can be 64 bits. It's also usually the number of seconds since Unix epoc, midnight, January 1, 1970.
If you're willing to live with assumption that the resolution is seconds and don't have to worry about the code working in 20 years (see: https://en.wikipedia.org/wiki/Year_2038_problem) then you might use (untested):
#include <netinet/in.h>
time_t cur_time;
uint32_t net_cur_time; // cur_time converted to network byte order
char obuf[40];
gmtime(&cur_time);
net_cur_time = htonl((uint32_t)cur_time);
SHA256(&net_cur_time, sizeof(net_cur_time), obuf);
I'll repeat what I mentioned in a comment: it's hard to understand what you possibly hope to gain from this hash, or why you can't use the timestamp directly. Cryptographically secure hashes such as SHA256 go through a lot of work to ensure the hash is not reversible. You can't benefit from that because the input data is from a limited known set. At the very least, why not use CRC32 instead because it's much faster.
Good luck.
I try to read value from binary file. I know offset (3201) and use it.
Example code:
FILE *bin_file;
int *job_id_buffer;
bin_file = fopen("sample.sgy", "rb");
if (bin_file == NULL)
{
// ... skipped ...
}
fseek(bin_file, 3201, SEEK_SET);
job_id_buffer = (int*)malloc(sizeof(int));
fread(job_id_buffer, sizeof(int), 1, bin_file);
printf("%d\n", (int)job_id_buffer[0]);
fclose(bin_file);
Looks like I don't know how to read value correctly.
But problem is that when I get result, the value is 993024, while I 100% know that correct value is 9999.
Could you, please, help me to understand what I do incorrectly?
Thank you in advance!
A quick look at the values you got:
Expected: 9999 = 0x0000270F
Received: 993024 = 0x000F2700
From this we can see two things:
0F27 is 270F with swapped bytes. Apparently, the byte order (endiannes) inside the file is not the same as that in memory;
If only the byte order was swapped, you would be getting 0x0F270000 from the file, but the value seems to be shifted by one byte.
This can mean one of two things, depending on the endianness of the file:
If the file is little-endian (and the CPU is big-endian), you should be seeking to offset 3202 instead of 3201.
If the file is big-endian (and the CPU is little-endian), you should be seeking to offset 3200 instead of 3201.
So, check the endianness of the file and correct your offset; then, convert the data read from the endianness of the file to the endianness of your CPU (reverse the bytes in this case) to get the correct value.
To create code that is correct on any CPU, you may be able to use be32toh(), or le32toh(), to convert big-endian, or little-endian respectively, file data to the right CPU endianness.
I have a basic problem using memcpy and don't understand where the problem is. I show below the relevant parts of the code. The code seg. faults in the last right iteration of the loop. Why can't I index in to an memory area that is reserved?
Thank you in advance.
mystr->data = malloc(2048);
unsigned char buf[8500];
for (i=0;i<32;i++){
offset = i*256;
memcpy(&mystr->data[64*i],&buf[8+offset],64);
}
From the comments it'cs clear that my suspicion was right:
if sizeof( *mystr->data ) > 1 (because e.g. it's unsigned long long *data;) then you run beyond the end of the buffer because the offsets calculated by expressions like &mystr->data[64*i] are relative to the type, here it is mystr->data + 64*i*sizeof(*mystr->data) bytes which was up to 64*31*8 in your code.
You could either change the type, as you have done, or change the offsets (to &mystr->data[8*i] in your case) depending on what what seems 'right' semantically in your context
Please help me.
I don't know why this program is not working.
Sorry, but I needed to post whole code so it can be understanded clearly.
I tried to put str in txt file and then read it again and it is the same problem.
Also, I tried changing pointers with some other and then sompareing them and also the samo problem.
Arguments of program are:
1) txt file - with something like this - xyxxyyyxyxxyxyyxyxyxyyyyxxxx...
2) number - example - 2 - means that i need to group symbols in pairs
Output should be probaillity of any combination of x and y (xx,yy,xy,yx - for group of 2).
example:
p(xx)=0.4
p(yy)=0.1
p(yx)=0.5
p(xy)=0
BUT!
this is ALWAYS TRUE:
if (str==lista[i])
WHY?
I am struggling with it for hours. :(
I tried what others suggested:
Look at this:
http://i.imgur.com/SL1L8hc.jpg and
http://i.imgur.com/QwZGdgM.jpg
Weirdest one:
http://i.imgur.com/BIeLXOu.gif
WHOLE CODE:
#include "stdio.h"
#include "string.h"
#include "stdlib.h"
typedef char * string;
int main(int argc, char *argv[]){
if (argc<3) {
return -1;
}
FILE *ul;
int mode,i,dane,j,razl;
char *str;
int brojac=0;
string lista[1000];
int pomlis[1000];
ul=fopen(argv[1],"r");
fseek(ul,0,SEEK_SET);
if (!ul){
return 1;
}
for (i=0;i<1000;i++){
lista[i]="nist";
pomlis[i]=0;
}
mode=atoi(argv[2]);
str=(char*)malloc(mode+1);
brojac=0;
razl=0;
while (fgets(str,sizeof(char)*mode+1,ul)!=NULL){
dane=0;
// printf("%s ",str); //da bi printao u konzolu
brojac++;
for (i=0;i<=razl;i++){
if (str==lista[i]){
pomlis[i]++;
dane=1;
}
}
if (dane==0){
if (lista[i]=="nist") i--;
lista[i+1]=str;
pomlis[i+1]=1;
razl++;
}
}
for (i=1;i<=razl;i++){
printf("p(%s)=%f\n",lista[i],pomlis[i]/((double)brojac));
}
fclose(ul);
return 0;
}
I tried all suggestions in the comments and nothing works. Does anyone knows the answer?
First of, sizeof(char) is 1 by definition. It doesn't make the code more readable.
The line
fgets(str,sizeof(char)*mode+1,ul);
reads into char *str which is allocated in
str=(char*)malloc(sizeof(char)*mode);
Which should omit the cast, and is too small to hold everything fgets() writes to it (by the +1 '\0').
In addition:
printf("p(%s)=%d\n",lista[i],pomlis[i]/brojac);
pomolis[i] and brojac are both integers, therefore the division will not return a fraction (float/double) but an integer again (most likely zero in your program).
Thank you all, edited, but, can I get answer? Why I am getting minuses on question if no one knows answer?
Well, try replacing the line
if (str==lista[i]){
with
if (!strncmp(str, &lista[i], mode){
and remove the line
fgets(str,sizeof(char)*mode+1,ul);
in the body of the while-loop (you are already calling fgets() in the while condition, don't call it twice)
Your code has many problems. I suggest reading about pointers, memory allocation and how strings work in c. Because of your typedef char * string i suppose you must be coming from a higher language then c. Forget that knowledge, you'll have big problems if you try to apply it here.
I've made it work, but I will not post the working code here, as I'm not interested in doing anyone's homework. I'll try to teach you what your problems are.
Your first problem is here:
for (i=0;i<1000;i++){
lista[i]="nist";
pomlis[i]=0;
}
Assigning "nist" to char * assigns the address of a constant string "nist" to the pointer. As the string is constant, if you later try to change something in it, you will fail.
You should use malloc, which allocates memory you can write to:
for (i=0;i<1000;i++){
lista[i]=(char*) malloc(5);
pomlis[i]=0;
}
Next, as others have explained, using == is quite different then using strncmp. You should use:
if (strcmp(str, lista[i])==0){
pomlis[i]++;
dane=1;
}
The next part makes absolutely no sense:
if (dane==0){
if (lista[i]=="nist") i--;
lista[i+1]=str;
pomlis[i+1]=1;
razl++;
}
First you're comparing to another pointer to constant string (note that "nist" you've initialized to doesn't have to be the same "nist" you have here). I really have no idea what you're trying to accomplish using i here.
I wrote it like this:
if (dane==0){
memcpy(lista[razl],str, sizeof(str));
pomlis[razl]=1;
razl++;
}
Try to understand this.
Finally, your for loops go to the limit i<=razl. As arrays are zero initialized, you should break before i hits razl.
if (str==lista[i])
Now, str and lista[i] are of type char*. That is they are pointers. In which case the == operator tests for equality of the pointer addresses. So, if this == operator evaluates true then the two pointers have the same address.
If you want to compare the value of the string then you must use strcmp().
Greetings!
I have a simple program in qt on c.
There are two pointers to type short, used to read from file and store bits from values read.
sample code:
//(input is a FILE* which is opened and passed to the function)
//(output is also a FILE* which is also opened and passed to the function)
//1. Variables declaration
short* sample_buffer;
int buffer_size=1;
short samples_read;
unsigned long value_x=7;
short* nzb_buffer;
short buffer_position=-1;
int i;
//2.Memory allocation
sample_buffer= malloc(sizeof(short)*buffer_size);
nzb_buffer = malloc(sizeof(short)*value_x);
....
//3. Read from infile, one short at time, process and write it to outfile
do
{
//3.1. Read from input file
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
//3.2. Switch position inside nzb_buffer one to the right,
// going back to zero if out of bounds
buffer_position=(buffer_position+1)%value_x;
....
//3.3. Put least significant bit of the just read short into nzb_buffer
nzb_buffer[buffer_position]=sample_buffer[0]%2;
....
//3.4. Write the short we just read from infile to the outfile
for (i=0;i<samples_read;i++)
{
fwrite(sample_buffer,sizeof(short),1, output);
}
} while(samples_read==buffer_size);
I've let unreliant pieces of code out. If you need to see something else please tell me.
Problem is, after like 10 or 15 operations of the loop, it crashes with "Segmentation fault" signal. It crashes on the fwrite() function.
I debugged and i use watch on sample_buffer. For some reason, on one exact step, the operation nzb_buffer[buffer_position]=sample_buffer[0]%2 makes sample_buffer become 0x0 (i belive, it becomes a null pointer).
This cannot be overflowing on nzb_buffer because buffer_position for that operation is 3 (out of 7 allocated for the particular array in malloc). And since each loop makes one write operation and shifts the carry, the operation of writing into nzb_buffer[3] has already happened before in the loop and did not nullify the pointer that time.
I am totally clueless what may be happening here.
Anybody has any ideas what is going on or how do i debug it?
Thanks in advance!
PS: Added comments "what the code does"
Your exit condition for the loop seems to be misplaced. I would do:
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
while(samples_read==buffer_size){
[...]
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
}