Increment Char Array Pointer - c

Is it possible to increment/advance a char array like I can a char pointer?
For example I can do this for a char pointer:
while (*cPtr)
printf("c=%c\n", *(cPtr++));
But I am not able to do this:
// char cArray[] = "abcde";
while (*cArray)
printf("c=%c\n", *(cArray++)); // Compile error: 19 26 [Error] lvalue required as increment operand
The purpose is to be able to iterate over a char array when I dont know the length of the array. My thinking is that I just want to advance till I find a null character I guess unless theres an easier way?
char a[] = "abcde";
int index = -1;
while (a[++index])
printf("c=%c\n", a[index]);

Is it possible to increment/advance a char array like I can a char pointer?
Unlike pointers, arrays are not lvalues and you can't modify it. That's a major difference between arrays and pointers.

Do something like that:
char cArray[] = "abc def";
char *p = &cArray[0];
while (*p)
printf("c=%c\n", *(p++));

You can do:
for(int i = 0; i < 5; i++) // if you know the length
printf("c=%c\n", a[i]);
or get the size with sizeof() and replace i < 5 with i < size:
int size = (sizeof(a) / sizeof(*a))

I have used this with success under keil uVision:
char buffer[512];
uint8_t var[512]; // uint8_t = integer 8bit
for(int i = 0; i < 128; i = i + 4)
sprintf(&buffer[i],"%03d,", var[y]); //this will put 4 bytes in buffer
Better way to do this:
char buffer[128];
uint8_t int_buffer[24]; // gets updated in an interrupt - some sensors values
uint8_t i = 0;
uint8_t PrintSize = 0;
while(/*myFile is smaller than 1Mb..*/)
{
PrintSize = 0;
i = 0;
while(i < 23)
{
PrintSize += sprintf(buffer + PrintSize,"%01d,",int_buffer[i]);
i++;
}
PrintSize += sprintf(buffer + PrintSize,"%01d\n", int_buffer[23]);
//write buffer to a file in my app
}
File content is like this:
41,1,210,243,120,0,210,202,170,0,14,28,0,0,0,1,85,0,5,45,0,0,0,1
40,1,215,255,119,0,215,255,170,0,14,37,0,0,0,1,85,0,5,46,0,0,0,1

Related

Unsigned char array concatenation in C

What's the best way to concatenate unsigned char arrays in C? Furthermore, is there a way to concatenate unsigned char arrays with char arrays? 2 of these unsigned char arrays are really just strings, but for simplicity, I'm treating them as unsigned char arrays.
The requirement is complex: there is a function that will take 1 (one) unsigned char array. That one unsigned char array is really 4 variables concatenated to make up that 1 unsigned char array. To add to the complexity, the first unsigned char array is really just a string of variable length, but its max length is 60 (i.e. sometimes it would have length = 15, other times = 60).
someFunctionAssignsFirst(unsigned char *first)
{
//it could be 15 or 60 chars long.
...
}
unsigned char first[60] = //someFunctionAssignsFirst() //This is a string i.e. "variable size string max size 60"
unsigned char second[8] = "always8."; //This is a string i.e. "01234567"
unsigned char third[32] = "always32"; //This is a cryptographic key
unsigned char fourth[32] = "always32"; //This is a cryptographic key
How would I go about getting:
unsigned char allstrings[sizeof(first)+sizeof(second)+sizeof(third)+sizeof(fourth)] = //all strings combined
?
I attempted some for loops, but the variable length first is disrupting the concatenation, and I'm sure there has to be a better way.
Full Disclosure: I'm not an expert, and I don't necessarily love C. Also for the requirement, not allowed C++ or any other language.
This is what I was trying to do, and (for clarification) I don't get a null character at the end so it's not really a string.
unsigned char *first = "this is a sample string, human readable";
unsigned char *second = "12345678" //always a number
//unsigned char third -> I have the value from before and it's a key
//unsigned char fourth -> I have the value from before and it's a key
unsigned char allstrings[sizeof(first) + sizeof(second) + sizeof(third) + sizeof(fourth)];
int counter = 0;
for (int i = 0; i <= sizeof(first); i++)
{
allstrings[counter] = first[i];
counter++;
}
for (int i = 0; i <= sizeof(second); i++)
{
allstrings[counter] = second[i];
counter++;
}
for (int i = 0; i <= sizeof(third); i++)
{
allstrings[counter] = third[i];
counter++;
}
for (int i = 0; i <= sizeof(fourth); i++)
{
allstrings[counter] = fourth[i];
counter++;
}
The allstrings variable, doesn't get anything beyond "readable" in my example above.
You need to use strcpy to copy over the first part, which is a string, then use memcpy to copy over the other 3, which are not strings but char arrays.
Note that the result is not a string but a char array, i.e. it is not null terminated.
unsigned char allstrings[strlen(first)+sizeof(second)+sizeof(third)+sizeof(fourth)];
strcpy(allstrings,first);
memcpy(allstrings+strlen(first),second,sizeof(second));
memcpy(allstrings+strlen(first)+sizeof(second),third,sizeof(third));
memcpy(allstrings+strlen(first)+sizeof(second)+sizeof(third),fourth,sizeof(fourth));
I guess you want to treat the array as buffer.
So it's fine to have the declarations,
but you don't need to define the content for this moment:
unsigned char first[60];
unsigned char second[8];
unsigned char third[32];
unsigned char fourth[32];
#define ALLSTRLEN sizeof(first) + sizeof(second) + sizeof(third) + sizeof(fourth)
unsigned char allstrings[ALLSTRLEN];
The code will keep the fixed size of arrays. and please notice that the arrays should be global or static for safety reasons.
Then you can copy the contents to arrays. I just put your code under main() to concatenate these arrays:
int main()
{
strcpy((char *)first, "this is a sample string, human readable");
// do something for second, third, fourth....
//
int counter = 0;
// first array is a normal string, we have to copy null character for it
for (int i = 0; i <= strlen((char *)first)+1; i++)
{
allstrings[counter] = first[i];
counter++;
}
for (int i = 0; i <= sizeof(second); i++)
{
allstrings[counter] = second[i];
counter++;
}
for (int i = 0; i <= sizeof(third); i++)
{
allstrings[counter] = third[i];
counter++;
}
for (int i = 0; i <= sizeof(fourth); i++)
{
allstrings[counter] = fourth[i];
counter++;
}
// allstrings is finished
}
Please notice this example just works in main() function; if you call a function to concatenate four arrays, the compiler has to pass the arrays as pointers, and the sizeof() will be wrong (equal to the pointer's size).
You can test the size by doing this:
printf("sizeof(second)=%d\n", sizeof(second));

Transferring values from a char array to an integer array in C programming

I am having the following problem. I have created a char array which represents a series of characters and numbers - this was designed to model a string read or got from a text file. I wish to then search this string using the "search" function defined below, pulling out only the numbers before 'H' and assigning to a separately defined integer array. I find when I use gdb, this function works fine. However, only part of the array is ever returned - the first 8 elements to be exact. Would anyone please be able to explain why this is from looking at the code below?
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void search(char buffer[], int size, int array[]);
int main (void)
{
char buffer[1000];
memset(buffer, 0, sizeof(buffer));
buffer[0] = 2;
buffer[1] = 'H';
buffer[2] = 3;
buffer[3] = 'H';
buffer[4] = 6;
buffer[5] = 'H';
buffer[6] = 4;
buffer[7] = 'H';
buffer[8] = 6;
buffer[9] = 'H';
buffer[10] = 7;
buffer[11] = 'H';
buffer[12] = 11;
buffer[13] = 'H';
buffer[14] = 12;
buffer[15] = 'H';
buffer[16] = 17;
buffer[17] = 'H';
int* array ;
array = malloc(sizeof(buffer) * sizeof(int));
search(buffer, sizeof(buffer), array);
for(int i = 0, n = sizeof(array); i < n; i++)
{
printf("array[%d] = %d\n", i, array[i]);
}
free(array);
}
void search(char buffer[], int size, int array[])
{
int position = 0;
for (int i = 0; i < size; i++)
{
if(buffer[i] == 'H')
{
*(array + position) = buffer[i-1];
position++;
}
}
}
The compiler outputs the following:
array[0] = 2
array[1] = 3
array[2] = 6
array[3] = 4
array[4] = 6
array[5] = 7
array[6] = 11
array[7] = 12
which as can be seen is missing the ninth position in the array - value 17. In fact, if I fgets into a buffer a much bigger set of numbers and 'H's, I am always returned an array of size 8. Why is this? Any help would be much appreciated.
The problem here is with
n = sizeof(array)
array being a pointer, sizeof(array) will give you the size of the pointer (as sizeof(array) here is essentially sizeof(int *), which seems to be 8 for your platform), not the cumulative size (or number of elements) in the array.
One possible way to get what you want will be the search() to return the count of element put into the array and use that return value in the for loop for printing the required elements from array.
Replace n = sizeof(array) with n = strlen(buffer) / 2 will do (you want n to be the number of filled elements in the array).
Btw,
You need to make sure the buffer always has correct pairs.
Would be safer to declare the buffer like this char buffer[1000] = "";
"I am always returned an array of size 8" - that's because sizeof(int) in 64b-machine is 8 bytes, which is what you got from sizeof(array) - as array here is pointer.

Populating a buffer from the return of a method fails... ANSI C

The code I have is quite simple in one method I have this:
// This line has an Intellisense Error: Initialization with {...} expected for aggregate object
char str[] = GetBuffer(); // x 64 will give us 512 (sector sized buffer) ;
The GetBuffer metod is this:
char * GetBuffer(void)
{
int idx = 0;
int offset = 0;
char *buffer[512];
for(idx =0; idx < 64; idx ++)
{
// This line has an Itellisense Error: "Expected Expression"
buffer[offset + idx] = {"E","R","A","S","E","D"," ", " "};
offset += 8;
}
return *buffer;
}
Any ideas what's wrong with this?
All I am trying to do - is populate a buffer with 512 bytes which contain the following string repeated: "ERASED " This is ANSI C (not C++) and it has been so long since I coded in ANSI C - please help and be kind!
Using Visual Studio 2012
EDIT 1
Ok lots of things have been fixed thanks to you guys - but no full answer yet.
The str buffer holds 528 characters and not 512 and contains a lot of ERASED as expected but ends with
ýýýý««««««««îþîþ
Any ideas with this? And Oh boy I have a great deal of pure C reading to do - I have forgotten way too much!
You can't initialize an array with the return value from a function.
You could use a pointer instead of an array:
char *str = GetBuffer();
Or you could use strcpy() or a relative — but there are buffer overflow risks:
char str[512];
strcpy(str, GetBuffer());
Your GetBuffer() function also has a lot of problems.
char *GetBuffer(void)
{
int idx = 0;
int offset = 0;
char *buffer[512];
This should probably be char buffer[512];, but...
for(idx =0; idx < 64; idx ++)
{
// This line has an Itellisense Error: "Expected Expression"
buffer[offset + idx] = {"E","R","A","S","E","D"," ", " "};
You can't set arrays like this. And you needed double quotes because of the char *buffer[512] problem.
offset += 8;
}
return *buffer;
}
And you should not return a local variable — it is destroyed when the function returns so it can't be used afterwards.
You might write:
char *GetBuffer(void)
{
char *buffer = malloc(257);
if (buffer != 0)
{
int idx;
for (idx = 0; idx < 256; idx += 8)
strcpy(buffer+idx, "ERASED ");
}
return buffer;
}
There's a small layer of obfuscation going on with the hard-coded lengths and limits; they're correct, but the interconnections between the sizes are not obvious — and ideally, they should be:
strlen("ERASED ") == 8
256 = 32 * strlen("ERASED ")
257 = 32 * strlen("ERASED ") + 1 (the one is for the terminal null)
And then the calling code might be:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
char *str = GetBuffer();
if (str != 0)
{
printf("<<%s>>\n", str);
free(str);
}
return(0);
}
there is problem with your buffer creation. you'd malloc such that it's not reclaimed by the function invoke routine. Second, you can't do assignment like the line you encountered a Itellisense error.
You can use this:
#include "stdlib.h"
char * GetBuffer(void)
{
int i = 0, idx = 0;
const char * cstr_init = "ERASED ";
char *buffer = (char*)malloc(512);
for (idx = 0; idx < 512; idx+=8) {
for (i = 0; i < 8; i++) {
buffer[idx+i] = cstr_init[i];
}
}
return buffer;
}
There are several things wrong here.
In C, a character array can be initialized with an initializer list or a string literal. You cannot use the return value from a function to initialize the array. So
char str[] = GetBuffer();
will not work.
Also, char* buffer [512] is an array of 512 pointers to char, i.e., an array of 512 strings. buffer [offset + idx] would be one pointer to char. It can hold only one string, but you are trying to assign eight strings to it: "E", "R", etc. If you mean those to be chars and not strings, use single quotes: 'E', etc. However, even that won't work unless you allocate memory to the pointer so that it can hold the string.
As written, the array of pointers is allocated on the stack, so it goes out of scope when the function terminates. return *buffer would return the first string in the array of strings, but that's a local variable, so you're returning the dereferenced value of a pointer that is no longer in scope.
I think a simpler way to accomplish your goal is this:
char str [512] = {'\0'};
for (int i = 0; i < 511; i += 7)
strcat (str + i, "ERASED ");
It's not very general, but it does what you want.
Edited to reflect Jonathan Leffler's comment that strcat (str, "ERASED "), which is what I originally had, is inefficient.

how to convert a int variable to char *array in C with malloc?

I'm doing a school project and this problem came up.
by the way, i can't use library.
How to convert a int variable to char array?
I have tried this but it didn't work, tried a lot of other things and even magic doesn't work...
char *r = malloc(sizeof(char*));
int i = 1;
r[counter++] = (char) i;
Can someone help me?
Thank you for your time.
In your code, you should allocate for char size and not char *. Please try with this code segment
char *r = malloc(sizeof(char) * N); // Modified here
int i = 1;
r[counter++] = i & 0xff; // To store only the lower 8 bits.
You could also try this:
char *r = malloc(sizeof(char));
char *s = (char*)&i;
r[counter++] = s[0];
This is an other funny way to proceed and it allows you to access the full int with:
s[0], s[1], etc...
Do you mind losing precision? A char is generally 8 bits and an int is generally more. Any int value over 255 is going to be converted to its modulo 255 - unless you want to convert the int into as many chars as is takes to hold an int.
Your title seems ot say that, but none of the answers give so far do.
If so, you need to declare an array of char which is sizeof(int) / sizeof(char) and loop that many times, moving i >> 8 into r[looop_var]. There is no need at all to malloc, unless your teacher told you to do so. In whch case, don't forget to handle malloc failing.
Let's say something like (I am coding this w/o compiling it, so beware)
int numChars = sizeof(int) / sizeof(char);
char charArry[numChard]; // or malloc() later, if you must (& check result)
int convertMe = 0x12345678;
int loopVar;
for (loopVar = 0; loopvar < numChars)
{
charArry[loopVar ] = convertMe ;
convertMe = convertMe >> 8;
}
If you can't use the library, you can't use malloc.
But this will work:
int i = 0;
char *p = (char *)&i;
p[0] = 'H';
p[1] = 'i';
p[2] = '!';
p[3] = '\0';
printf("%s\n", p);
Assuming your int is 32bit or more (and your char is 8).
It then follows that if you have:
int i[100];
You can treat that as an array of char with a size equal to sizeof (i). i.e.
int i[100];
int sz = sizeof(i); // probably 400
char *p = (char *)i; // p[0] to p[sz - 1] is valid.
You can use a union instead. Assuming that sizeof int == 4,
typedef union {
int i;
char[4] cs;
} int_char;
int_char int_char_pun;
int_char_pun.i = 4;
for (int i = 0; i < 4; i++) {
putchar(int_char_pun.cs[i]);
}
Be careful; int_char.cs usually won't be a null-terminated string, or it might be, but with length < 4.
if you don't want to include the math library:
unsigned long pow10(int n);
void main(){
char test[6] = {0};
unsigned int testint = 2410;
char conversion_started = 0;
int i=0,j=0;float k=0;
for(i=sizeof(test);i>-1;i--){
k=testint/pow10(i);
if(k<1 && conversion_started==0) continue;
if(k >= 0 && k < 10){
test[j++]=k+0x30;
testint = testint - (k * pow10(i));
conversion_started=1;
}
}
test[j]=0x00;
printf("%s",test);
}
unsigned long pow10(int n){
long r = 1;
int q = 0;
if(n==0) return 1;
if(n>0){
for(q=0;q<n;q++) r = r * 10;
return r;
}
}
NOTE: I didn't care much about the char array length, so you might better choose it wisely.
hmm... what is wrong with the code below
char *r = malloc(sizeof(char) * ARR_SIZE);
int i = 1;
sprintf(r,"%d",i);
printf("int %d converted int %s",i,r);
will it now work for you

How to create a new array but use the same variable in C?

The reason why I am stuck on this is because of how C handles arrays, which is through pointers which I am new at. This is my case(not exactly my problem but a simplistic case):
char *keywords[k_num_of_keywords];
for(int i = 0; i < k_num_of_keywords; i++) {
char temp[] = "float";
keywords[i] = temp;
}
In this case, it would put float in all the indexes, but more importantly, the same address of wherever the string "float" is located. My case is slightly different, because I want to automate initializing a new char array for each index, but still use the same variable, rather than the same address in each index. How can I accomplish this in a for loop?
You should allocate memory for every element for "keywords", for example:
char *keywords[k_num_of_keywords];
for(int i = 0; i < k_num_of_keywords; i++) {
char temp[] = "float";
int len = strlen(temp);
keywords[i] = (char *)malloc(sizeof(char) * (len + 1));
memcpy(keywords[i], temp, len + 1);
}

Resources