Split Char into single variables

Thread Starter

pleditor

Joined Feb 19, 2013
4
I need to split one large Char into 2 or more smaller chars. I could not find any possibility to do this with MikroC Pro.

Rich (BB code):
  char string[] = "abcdef";
  
  char stringA;     //should be "abc"
  char stringB;     //should be "def"
Any help on this? I just started with pic programming :confused:
 

Papabravo

Joined Feb 24, 2006
21,159
stringA[0] = string[0] ;
stringA[1] = string[1] ;
stringA[2] = string[2] ;
stringA[3] = '\0' ;

stringB[0] = string[3] ;
stringB[1] = string[4] ;
stringB[2] = string[5] ;
stringB[3] = '\0' ;

Indexes for the second set of assignments have been corrected. Everybody makes occasional mistakes.
 
Last edited:

THE_RB

Joined Feb 11, 2008
5,438
MikroC supports the standard ANSI string functions like strcpy() and memcpy().
Like this;
strcpy(stringA,string+3); // puts "def" in stringA

memcpy() lets you tell it how many chars to copy. You may need to add a NULL char to the end yourself, if that is needed.

You can also display the last part of a string simply by offsetting the pointer by X bytes;
char string[] = "abcdef";
display(string+3); // result displayed is "def"

string[3] = 0; // add a NULL to end string after 3 chars
display(string); // result displayed is "abc"

You should have a look through the MikroC help file, it is pretty good and will explain all the string and display type functions.
 

Papabravo

Joined Feb 24, 2006
21,159
On the theory that you need to crawl before you walk, a method that does not rely on library functions lays the groundwork for using them after you understand the mechanics of what is going on. I could have used a more general technique but the overhead of setting up a loop probably takes more code than the straightforward method.

I should have mentioned that stringA and srtingB need to be declared as having AT LEAST 4 elements; three for the characters and one to hold the null terminator.

char stringA[4] ;
char stringB[4] ;

To avoid problems with character comparisons I always declare char to be unsigned.

unsigned char stringA[4] ;
unsigned char stringB[4] ;
 

Thread Starter

pleditor

Joined Feb 19, 2013
4
MikroC supports the standard ANSI string functions like strcpy() and memcpy().
Like this;
strcpy(stringA,string+3); // puts "def" in stringA

memcpy() lets you tell it how many chars to copy. You may need to add a NULL char to the end yourself, if that is needed.

You can also display the last part of a string simply by offsetting the pointer by X bytes;
char string[] = "abcdef";
display(string+3); // result displayed is "def"

string[3] = 0; // add a NULL to end string after 3 chars
display(string); // result displayed is "abc"

You should have a look through the MikroC help file, it is pretty good and will explain all the string and display type functions.
Great! that helped me :) However i have now some memory issues because of many variables xD. Thanks everybody, learned a lot in a short time ;-)
 

THE_RB

Joined Feb 11, 2008
5,438
On the theory that you need to crawl before you walk, a method that does not rely on library functions lays the groundwork for using them after you understand the mechanics of what is going on.
...
Sorry Papabravo that may have looked like I was trying to show a "better" solution than yours after you already helped the OP, that was not my intent. Your method was very clear and I understood that you were keeping it to the most basic elements needed. Your method also uses less code space and will likely execute faster in code than a lot of string library options. :)

It's just that the OP mentioned MikroC and as MikroC user I knew there were always string functions available in that compiler.

Looking back now I should have said "As well as Papabravo's example your compiler also has inbuilt functions that provide other ways of doing it".

Sorry for any misunderstanding.
 

takao21203

Joined Apr 28, 2012
3,702
String library coders have notoriously weak attitudes or are forced into a corporate corset.

What we need is the one or other Assembler Whiz. Trying to be talkative.

In C there are many ways to solve a problem.
 

thatoneguy

Joined Feb 19, 2009
6,359
This is also a good place to start treading lightly with pointers.

Enough to understand passing by reference vs. value, and for traversing strings.

Once you fully understand arrays, then understanding memset/memcpy includes a bit of knowledge on passing by reference.

Passing by reference allows a function to modify a variable in situ (in place), rather than pushing a copy of a string onto the stack. The "Reference" is a pointer to the string at point.

roughly:
& means "Address of"
* means "Value at address"

You'll often see these in function references, such as this example:

C Reference String Operation: memcpy()

The function memcpy() copies n characters from source to target.
Usage:

void *memcpy(void *target, void *source, size_t count);
Note: If the copy takes place between objects that overlap, the behaviour is undefined.
Rich (BB code):
#include[SIZE=+1]<[/SIZE]stdio[SIZE=+1].[/SIZE]h[SIZE=+1]>[/SIZE] 
#include[SIZE=+1]<[/SIZE]string[SIZE=+1].[/SIZE]h[SIZE=+1]>[/SIZE]  

main [SIZE=+1]([/SIZE][SIZE=+1])[/SIZE] 
[SIZE=+1]{[/SIZE]   
char line[SIZE=+1][[/SIZE]100[SIZE=+1]][/SIZE][SIZE=+1];[/SIZE]   
char [SIZE=+1]*[/SIZE]ptr_my[SIZE=+1];[/SIZE]    
ptr_my [SIZE=+1]=[/SIZE] [SIZE=+1]&[/SIZE]line[SIZE=+1][[/SIZE]0[SIZE=+1]][/SIZE][SIZE=+1];[/SIZE]   
strcpy [SIZE=+1]([/SIZE]ptr_my[SIZE=+1],[/SIZE] "aaa"[SIZE=+1])[/SIZE][SIZE=+1];[/SIZE]    
memcpy [SIZE=+1]([/SIZE][SIZE=+1]&[/SIZE]ptr_my[SIZE=+1][[/SIZE]3[SIZE=+1]][/SIZE][SIZE=+1],[/SIZE] "bbb"[SIZE=+1],[/SIZE] 3[SIZE=+1])[/SIZE][SIZE=+1];[/SIZE]   
ptr_my[SIZE=+1][[/SIZE]6[SIZE=+1]][/SIZE] [SIZE=+1]=[/SIZE] '\0'[SIZE=+1];[/SIZE]    
printf [SIZE=+1]([/SIZE]"%s\n"[SIZE=+1],[/SIZE] ptr_my[SIZE=+1])[/SIZE][SIZE=+1];[/SIZE] 
[SIZE=+1]}[/SIZE]
Compiling the above and running on linux gives the output of:

~/code$ vi memcpy.c
~/code$ cc -o mem memcpy.c
~/code$ ./mem
aaabbb
Similar results will be found with a microcontroller,
provided you are using an LCD or serial output device. AVOID USING printf() or scanf() functions with a uC, they are HUGE functions, there are better ways of outputting text than by using those libraries.

memcpy works with a fixed number of memory locations.
strcpy works with strings (copy until \0 or NUL is found to terminate string)
strncpy works with a fixed number or NUL

The great part is that you don't need to copy the entire string, you can start at any offset, and copy any number of characters. For example get half a full buffer, you can use sizeof(buffer)/2 as number of characters to copy. This will not get half the string, only half the allocated buffer size. To get half the string size, use strlen(buffer)/2 and you have half your string, no matter the size.

**The important part to remember is pointers will allow you to overwrite other data, there isn't bounds checking to ensure you aren't writing outside the bounds of the strings you are working with!!!***
(Some development environments will perform Static Code Analysis, and warn you if you are potentially going over the boundaries of an allocated space, but this is NOT a common feature of low cost compilers)

A wonderful command that will save a lot of time is memset.

Rich (BB code):
char serialbuffer[128];

memset(serialbuffer,'\0',sizeof(serialbuffer));
The above will "Clear" a buffer of old data so it will not interfere with new data copied in, or to initialize a string.

For a GREAT resource on C functions, click the hotlink above that takes you to a great C resource site.

When managing strings, allocating only enough memory to hold the data, and passing the data by reference rather than by value (putting a copy on a stack), you can cut down on both program size and RAM usage a great deal.
 
Last edited:

takao21203

Joined Apr 28, 2012
3,702
On controllers you can do things you'd not want to do in a Windows software. For instance save yourself from dealing with parameter passing and use global variables.

Also array is only a different notation for pointers. They are exchangeable.

You'd for instance sometimes want to handle a collection of data bytes with a char pointer. Then you can add let say 10 for dimension Y, and 1 for X.

Understanding the representation of a storage item is essential as well how you can create a copy of it or a partial copy, and how to index into it.

OPs way of asking demonstrates there is yet a gap in understanding.
 

MrChips

Joined Oct 2, 2009
30,712
stringA[0] = string[0] ;
stringA[1] = string[1] ;
stringA[2] = string[2] ;
stringA[3] = '\0' ;

stringB[0] = string[4] ;
stringB[1] = string[5] ;
stringB[2] = string[6] ;
stringB[3] = '\0' ;
Minor typo above.
Corrected below:
Rich (BB code):
stringB[0] = string[3] ;
stringB[1] = string[4] ;
stringB[2] = string[5] ;
stringB[3] = '\0' ;
 

Papabravo

Joined Feb 24, 2006
21,159
@Mr. Chips -- thanks for the correction
@THE RB -- I took no offense at your post. More information is always better than less information. Some might have interpreted my post as trivial or impertinent, and I can assure everybody that it was not my intent. There are some non-obvious points about how the syntax and semantics of sting hanling are done in C, that are rooted in the earliest generation of machines that hosted C-compilers such as the PDP-7.
 
Top