473,386 Members | 1,864 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

Concatenating multiple strings into single string while preserving terminating NULL

Markus
6,050 Expert 4TB
Hi, guys.

I'm receiving a dynamic amount of strings and from these strings I need to make a single string containing them all. However, I need to preserve the NULL characters to separate the strings. If you see this page of documentation and scroll down to the REG_MULTI_SZ entry, you'll see the layout of the string needed.

My thoughts on how I would go about this are:
Expand|Select|Wrap|Line Numbers
  1. var full_string // empty
  2.  
  3. foreach strings as string:
  4.     reallocate memory for string based on full_string's length and string's length multiplied by sizeof char.
  5.     concatenate string to empty_string using strcat.
  6.  
The trouble is then how do I include the terminating nulls, and once again for the final null (the string should be terminated with 2)?

I'll give you what I've tried when I have some time.

Mark.
Nov 10 '10 #1

✓ answered by donbock

This will be a merciless code review. Remember that most of the comments will be stylistic; hence reasonable people may differ.
  1. Line 4. Suggest using "static const char * const" instead of "char *". Static makes this a static variable rather than an automatic variable; the initialization occurs once, not each time the function is called. The second const makes the array elements constant (you can't change them to point at other strings). The first const prevents you from changing the strings themselves via names_array.
  2. Line 7. Split off the definition of elements_count into its own line. Then you can use "static const int" for elements_count instead of "int". Use of static and const here is for the same reasons described above for line 4.
  3. Line 7. Change elements_count initializer such that the denominator is "sizeof(names_array[0])" instead of "sizeof(char*)". This relieves you of the responsibility to keep track of the type of the array elements.
  4. Line 15. You should check if realloc failed.
  5. Line 21. You didn't realloc names_string to make room for the terminating null. (Don't forget to check for failure if you call realloc again.)
Only the last two comments are definite problems.

4 2452
donbock
2,426 Expert 2GB
The output is not itself a string because it contains embedded null characters. You need to allocate a memory buffer big enough to hold all of the strings, including all necessary null characters. Then you can copy each string to the output buffer using either memcpy or strcpy, just be sure to offset the destination address to point where the next multi-string should go.
Nov 11 '10 #2
Markus
6,050 Expert 4TB
Yo, Donbock.

Here's a quick try; it works, but I could use your expert's eye:
Expand|Select|Wrap|Line Numbers
  1. int main (int argc, char *argv[])
  2. {
  3.     char *names_string  = NULL;
  4.     char *names_array[] = {
  5.         "mark", "jeff", "josh"
  6.     };
  7.     int elements_count = sizeof names_array / sizeof(char *),
  8.         i, offset = 0;
  9.  
  10.     for (i = 0; i < elements_count; i++)
  11.     {
  12.         /* Include terminating NULL */
  13.         int name_len = strlen(names_array[i]) + 1;
  14.  
  15.         names_string = realloc(names_string, offset + name_len);
  16.         memcpy(names_string + offset, names_array[i], name_len);
  17.  
  18.         offset += name_len;
  19.     }
  20.  
  21.     names_string[offset] = '\0';
  22.  
  23.     while (*names_string)
  24.     {
  25.         printf("name: %s\n", names_string);
  26.         names_string += strlen(names_string) + 1;
  27.     }
  28.  
  29.     return 0;    
  30. }
  31.  
Nov 11 '10 #3
donbock
2,426 Expert 2GB
This will be a merciless code review. Remember that most of the comments will be stylistic; hence reasonable people may differ.
  1. Line 4. Suggest using "static const char * const" instead of "char *". Static makes this a static variable rather than an automatic variable; the initialization occurs once, not each time the function is called. The second const makes the array elements constant (you can't change them to point at other strings). The first const prevents you from changing the strings themselves via names_array.
  2. Line 7. Split off the definition of elements_count into its own line. Then you can use "static const int" for elements_count instead of "int". Use of static and const here is for the same reasons described above for line 4.
  3. Line 7. Change elements_count initializer such that the denominator is "sizeof(names_array[0])" instead of "sizeof(char*)". This relieves you of the responsibility to keep track of the type of the array elements.
  4. Line 15. You should check if realloc failed.
  5. Line 21. You didn't realloc names_string to make room for the terminating null. (Don't forget to check for failure if you call realloc again.)
Only the last two comments are definite problems.
Nov 11 '10 #4
Markus
6,050 Expert 4TB
Very much appreciated, Donbock. :)
Nov 11 '10 #5

Sign in to post your reply or Sign up for a free account.

Similar topics

3
by: hokiegal99 | last post by:
How do I say: x = string.find(files, 'this', 'that', 'the-other') currently I have to write it like this to make it work: x = string.find(files, 'this') y = string.find(files, 'that') z =...
8
by: lasek | last post by:
Hi all, a simple question, look at this code below: char acName="Claudio"; unsigned int uiLen; uiLen=strlen(acName); printf("Length of acName variable %u",uiLen); //uiLen >>>> 7
5
by: Maury Markowitz | last post by:
I have a byte returned from a DLL that contains n c-style strings inside it. Any suggestions on how to easily pull them out into a string? Encoding helps with a single byte array (although easily...
1
by: pxllyte | last post by:
The input file data size is unknown so I would have to use malloc( ) to allocate enough memory for the file data. In order to do this, I would need to read each character of the file possibly by...
6
by: HeEm | last post by:
In my 100 level CS course, I was asked to create multiple lines of output within a single string. Of course I know how to: print "I am" print "a python" print "newbie." How can I get this...
6
by: msswift | last post by:
Hello everyone, unfortunately I didnt find any useful information using FAQ. Thats why Im asking this question here: How can I remove the terminating null-character from C string? I tried some...
1
by: gwigg | last post by:
Hi, I am trying to match multiple strings per line from a file and extract them into an array. Apparently the first match is assigned $1, how do I know what the last match is ie $last?? I would like...
3
by: Scott Sharkey | last post by:
Hi All, I have a need to determine whether a passed variable is a single string, or a list of strings. What is the most pythonic way to do this? Thanks. -Scott
4
by: Polarism | last post by:
Hello, I am very new to perl and I am having trouble figuring out how to replace multiple strings in a single file. The file has something around 750k instances that need to be replaced with 350...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.