How to put data from a buffer to an array in C? - c

I have got some data in a buffer and want to put those data in an array.
typedef struct chunk
{
char data[300]; /* the bufferr. */
} CHUNK;
char *buffer, CHUNK c [100];
Assuming I have got data into the buffer, how can I put 300 char per chunk? I'm new to C so please explain me with simple example.
Thanks,
Kevin

The declaration is invalid, but I think you mean:
typedef struct chunk
{
char data[300]; /* the bufferr. */
} CHUNK;
char *buffer;
CHUNK c [100];
If I understand your question correctly (which I'm far from certain that I do), the code would be something like:
int j = 0;
char *bp = buffer;
while (*bp)
{
strncpy (c [j] .data, bp, 300); // copy data into next item
bp += strlen (bp);
++ j;
}

In C, you can copy memory from one area to another using memcpy(). The prototype for memcpy() is:
void *memcpy(void *dst, const void *src, size_t n);
and the description is that it copies n bytes from src to dst, and returns dst.
So, to copy 300 bytes from b to a where both a and b point to something useful, b has at least 300 bytes of data, and a points to at least 300 bytes of space you can write to, you would do:
memcpy(a, b, 300);
Now your task should be something along the lines of:
typedef struct chunk
{
char data[300];
} CHUNK;
char *buffer;
CHUNK c[100];
size_t i;
/* make buffer point to useful data, and then: */
for (i=0; i < 300; ++i)
memcpy(c[i].data, buffer+i*300, 300);

You can use strncpy.
strncpy( data, buffer, 299 ) ;
Leaving the last index for the termination character '\0'. Or make the array size 301 and then use strncpy for 300 elements.

Related

How to reuse an array to write very fast to a big file in C

I am trying to write fast to a big file and using array. So I have to use same array multiple times. Part of my program is as follows.
char buff[1024];
char *x= buff;
fd = open("file.txt",O_CREAT|O_RDWR, S_IRWXU) ;
void function(){
char temp[128];
sprintf(temp,"%s,%s,%d\n",src,dst,payload) ;
x=myStrCat(x,temp); // copy files from temp to buff
//This is my question. if the buffer "buff" is full, how to truncate the buffer for next loop and that too fast.
if (strlen(buff) >= 1024){
write(fd,buff, len);
}
}
char * myStrCat(char * dest, char * src){
while(*dest) dest++;
while( *dest++ = *src++);
return --dest;
}
int main(){
//other codes
while (true){
function();
//conditions to break the loop untill then function() will be continuously in loop.
}
return 0;
}
Thanks in Advance!
strlen(buf) can never be >= 1024, since you only allocate 1024 bytes for it. C string requires a NULL to be in the end, so you will get a buffer overrun, which leads to undefined behaviour. You could have 1023+NULL, though.
Your code doesn't check if there will be a buffer overrun in the myStrCat either. It will cause undefined behaviour. What if you already have 1020 characters and want to add another 10?
The way you should do this is to keep a number indicating how many characters you already have in the buffer. If the buffer can't hold the next string, write the data into the file and zero the character count. If it can, copy the string to the buffer starting at the position indicated by the character count and get the next one.
Of course in the end write what's in the buffer to the file.
This way you will not run over the buffer limits.
(Are you sure this will be a lot faster than just letting the OS handle the write caching?)
Maybe you are looking for somwthing like this:
#define BUFFER_SIZE 1024
char buff[BUFFER_SIZE];
uint16_t buff_len = 0;
void function(){
char temp[128];
int len = sprintf(temp,"%s,%s,%d\n",src,dst,payload) ;
if ((len+buff_len) > BUFFER_SIZE-1)
{
write(fd,buff, buff_len);
buff_len = 0;
}
strcpy(&buff[buff_len],temp); // copy files from temp to buff
buff_len += len;
}

copy data from a memory address to another memory address, 752 bytes at a time

i want to copy data from a memory address to another memory address, 752 bytes at a time . without the for loop i am able to copy 752 bytes just once. how do i do it again and again 480 times and i need to increment my destination address so that all the 752 bytes data gets stored one after another in destination memory block. how can i do that? this is the solution that i came up with but its not working please help. Thank you .
volatile unsigned char *DAQ_BUFF = (unsigned char *)0xC6010000;
extern unsigned char *DAQ_BUFF;
unsigned char *Dest = (unsigned char *)0xC6020000;
int lv;
for(lv=0;lv<480;lv++)
{
memcpy(Dest,DAQ_BUFF,752);
Dest=Dest+752;
}
Four things i noticed:
You are using memcpy 3 times
You dont increment DAQ_BUFF as Rowland said
You are using memcpy(&Dest,&DAQ_BUFF,300); instead of memcpy(Dest,DAQ_BUFF,300);
And Dest is not initialized
unsigned char *Dest = something;
int lv;
for(lv = 0; lv < 480; lv++){
memcpy(Dest, DAQ_BUFF, 752);
Dest += 752;
DAQ_BUFF += 752;
}
valter
I think that small change in your loop will satisfy the situation
Here is the modified loop
volatile unsigned char *DAQ_BUFF = (unsigned char *)0xC6010000;
extern unsigned char *DAQ_BUFF;
unsigned char *Dest;
int lv,rv;
for(lv=0;lv<480;lv++)
{
memcpy(&Dest,&DAQ_BUFF+752*lv,300);
memcpy(&Dest+300,&DAQ_BUFF+300+752*lv,300);
memcpy(&Dest+600,&DAQ_BUFF+600+752*lv,152);
Dest=Dest+752;
}
I think the following should work, see my comment on your question for an explanation. Can you explain to me why the memcpy only goes in steps of 300 bytes?
volatile unsigned char *DAQ_BUFF = (unsigned char *)0xC6010000;
extern unsigned char *DAQ_BUFF;
unsigned char *Dest = (unsigned char *)0xC6020000;
int lv;
for(lv=0;lv<480;lv++)
{
memcpy(Dest, DAQ_BUFF, 300);
memcpy(Dest+300, DAQ_BUFF+300, 300);
memcpy(Dest+600, DAQ_BUFF+600, 152);
Dest += 752;
}
Your code makes me assume that DAQ_BUFF is large enough to hold 752 bytes. The reason for me to assume this is because there is no signal/flag checking to see if the 'next 300' bytes of data is 'valid' in your DAQ_BUFF. If you do need to check this I would have expected something like this:
for(lv=0;lv<480;lv++)
{
while (DAQ_BUFF_DATA_IS_NOT_VALID); /* wait for DAQ data to be valid */
memcpy(Dest, DAQ_BUFF, 300);
/* if DAQ_BUFF can only hold 300 bytes then it must be read from the beginning again */
while (DAQ_BUFF_DATA_IS_NOT_VALID); /* wait for DAQ data to be valid */
memcpy(Dest+300, DAQ_BUFF, 300);
while (DAQ_BUFF_DATA_IS_NOT_VALID); /* wait for DAQ data to be valid */
memcpy(Dest+600, DAQ_BUFF, 152);
Dest += 752;
}
That seems more like a piece of code that has a DAQ_BUFFER_SIZE of 300.
If that is not the case and your DAQ_BUFFER_SIZE is large enough to commodate the 752 bytes I would expect the following:
for(lv=0;lv<480;lv++)
{
/* Do you first need to check if DAQ_BUFF-data is valid? */
memcpy(Dest, DAQ_BUFF, 752);
Dest += 752;
}
int a[5] = {1,2,3,4,5}
int *p = a;
for(i=0;i<5;i++)
{
printf("array value is %d pointer poiniting to %p ",*(p+i),p);
}
if you run this code everytime the value of p will be same
as u are incrementing the pointer only adding it. fix the incrementation either like
p = p+1;
p++;
In your case Dest and DAQ_BUFF.
Note: check if you have initialized the pointers correctly.(May be the code is missing )
or it will pointing to random memory

strncpy() and memcpy() are different?

strncpy() and memcpy() are the same?
Because of the fact that strncpy() only accepts char * as parameter,
Icasts the integer arrays to char *.
Why it gets the different output?
Here is My code,
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#define SIZE 5
void print_array(int *array, char *name ,int len) {
int i;
printf("%s ={ ",name);
for(i=0; i<len;i++)
printf("%d," ,array[i]);
printf("}\n");
}
int main(void){
char string1[SIZE] = {'1','2','3','4','\0'};
char string2[SIZE], string3[SIZE];
int array1[SIZE] = {1,2,3,4,5};
int array2[SIZE],array3[SIZE];
strncpy(string2,string1,sizeof(string1));
memcpy(string3, string1,sizeof(string1));
printf("string2 =%s \n",string2);
printf("string3 =%s \n",string3);
strncpy((char *)array2, (char*)array1 , sizeof(array1));
memcpy(array3,array1,sizeof(array1));
print_array(array2,"array2",SIZE);
print_array(array3,"array3",SIZE);
return 0;
}
It turns out
string2 =1234
string3 =1234
array2 ={ 1,0,0,0,0,}
array3 ={ 1,2,3,4,5,}
But Why? It gives different answer?
strncpy((char *)array2, (char*)array1 , sizeof(array1));
Casting array1 to a char * doesn't do what you want. There are no characters at that location, there are only integers (little-endian it seems).
What is happening is that strncpy copies bytes from the integer array until it reaches a 0 byte, which is pretty soon. On the other hand memcpy doesn't care about 0 bytes and just copies the whole thing.
To put it another way, strncpy finds a 0 byte "inside" the first integer and stops copying; it does however fill the destination buffer with zeros up to the specified size.
You can implement (sort of) strncpy with memcpy, but the other way around won't work, because strncpy stops at the "end of the string", which doesn't work at all well for data that isn't a C style string (e.g. has zero bytes in it).
To write strncpy with memcpy would be something like this:
char *strncpy(char *dest, const char *src, size_t maxlen)
{
size_t len = strlen(src);
memcpy(dest, src, min(len, maxlen));
if (len < maxlen) memset(dest+len, 0, maxlen-len);
return dest;
}
(Note: The above implementation doesn't work for the case where the src string is not terminated correctly - a real strncpy does cope with this - it could be fixed in the above code, but it gets quite complicated).

C adding one char to buffer

I would like to ask how to add one char to a buffer. For example:
char buffer[50];
char one_symbol;
How to add one_symbol to buffer? I don't know how long the buffer is at the time, so I cant just write, for example buffer[5] = one_symbol;
Thanks.
You need to do something to keep track of the length of the data in the buffer.
You have a couple of choices about how to do that. Strings store data in the buffer (a NUL byte) to signal where there data ends. Another possibility is to store the length externally:
typedef struct {
char data[50];
size_t len;
} buffer;
This latter is particularly preferable when/if you want to allow for data that itself might include NUL bytes. If you don't want your buffer size fixed at 50, you can go a step further:
typedef struct {
size_t allocated;
size_t in_use;
char data[];
};
Note that this uses a flexible array member, which was added in C99, so some older compilers don't support it.
Keep track or the buffers current size. You can do it by adding a new variable for that.
Something like:
char buffer[50];
size_t current_size = 0; /* Buffer is of size zero from the size */
/* ... */
/* Add one character to the buffer */
buffer[current_size++] = 'a';

How to concat two char * in C?

I receive a char * buffer which have the lenght of 10.
But I want to concat the whole content in my struct which have an variable char *.
typedef struct{
char *buffer;
//..
}file_entry;
file_entry real[128];
int fs_write(char *buffer, int size, int file) {
//every time this function is called buffer have 10 of lenght only
// I want to concat the whole text in my char* in my struct
}
Something like this :
real[i].buffer += buffer;
How can I do this in C ?
In general, do the following (adjust and add error checking as you see fit)
// real[i].buffer += buffer;
// Determine new size
int newSize = strlen(real[i].buffer) + strlen(buffer) + 1;
// Allocate new buffer
char * newBuffer = (char *)malloc(newSize);
// do the copy and concat
strcpy(newBuffer,real[i].buffer);
strcat(newBuffer,buffer); // or strncat
// release old buffer
free(real[i].buffer);
// store new pointer
real[i].buffer = newBuffer;
You can use strcat(3) to concatenate strings. Make sure you have allocated enough space at the destination!
Note that just calling strcat() a bunch of times will result in a Schlemiel the Painter's algorithm. Keeping track of the total length in your structure (or elsewhere, if you prefer) will help you out with that.
I am not clear. Do you want:
to concatenate every one of the 10 character buffers you receive into one array, pointed at by one real[0].buffer, or
do you want each 10 character buffer to be pointed at by a different real[i].buffer, or
something else?
You will need to allocate enough space for the copy of the buffer:
#include <stdlib.h>
//...
int size = 10+1; // need to allocate enough space for a terminating '\0'
char* buff = (char *)malloc(size);
if (buff == NULL) {
fprintf(stderr, "Error: Failed to allocate %d bytes in file: %s, line %d\n",
size, __FILE__, __LINE__ );
exit(1);
}
buff[0] = '\0'; // terminate the string so that strcat can work, if needed
//...
real[i].buffer = buff; // now buffer points at some space
//...
strncpy(real[i].buffer, buffer, size-1);

Resources