Char array joining

Started by
19 comments, last by Zahlman 17 years, 1 month ago
Quote:Original post by honnyjopper
'\0' and NULL are identical here


No, NULL is only guaranteed to work as a pointer constant. In fact, some compilers even define NULL as ((void*)0), which is incompatible with the above usage.
Advertisement
Quote:What the? I think someone is mixing up NULL (the invalid pointer) and NUL (the terminator character). The literal you're looking for is '\0'.
Well, I've never seen a compiler that's as pedantic as to complain about this... plus Visual Assist lights up the NULL macro in purple so I'll stick with my pretty code thank you.

I also think it reads better, people say 'null terminated string' right? *dest = 0 seems to imply some kind of intent here, like you want to set the character to zero not just wrap up the end of the string.

Quote:Your suggestion of avoiding unnecessary traversal stands (even though an strcpy + strcat approach is still linear, and you still have to do those strlen anyway). If I were to handle it as a clean function, I'd probably write:

This is, I believe, the safest you can get in C. In the end, I'd rather spend time getting std::string to work, than rewriting it myself in C...

But this is for a PIC, I can't imagine that you'd care so much about safety that you'd sacrifice all that time doing strlen and malloc ... maybe some kind of stack alloc function would be a compromise?

I agree though that my strcypcat function isn't perfect, but it's got a cryptic name and does the job in a cheap and cheerful manner - which means it fits in pretty well along side the other C standard library functions :-)
Quote:Original post by Hidden Asbestos
Well, I've never seen a compiler that's as pedantic as to complain about this... plus Visual Assist lights up the NULL macro in purple so I'll stick with my pretty code thank you.

I also think it reads better, people say 'null terminated string' right? *dest = 0 seems to imply some kind of intent here, like you want to set the character to zero not just wrap up the end of the string.


1° "I've never seen [X] which does [Y]" is an award-winning "famous last words" quote. Chances are, you will someday, when working on a strange architecture with a strange compiler, encounter this oddity.
2° These boards are not powered by Visual Assist. At least on my computer, your NULL is in a flashy black font on a white background. Or did you pull this function straight out of one of your projects?
3° In C, 'null' means a lot of things. NULL means one of these things, and null-terminated means another. The two are not interchangeable. A null pointer is yet another thing, and a null string is still another, and so on. Hence my question: since you use a 'null pointer constant' as a 'null terminator', why not use a 'null string' as a 'null pointer constant'? #define NULL "" ...
4° It does not read better. Any experienced C or C++ programmer will spend at least 10 seconds wondering why your array of characters has suddenly become an array of pointers, and only then realize that you're (against the C standard) using NULL as the NUL string terminator. And then, spend a few more seconds weeping (I sure did).
5° *dest ='\0'; cannot be interpreted as anything other than "null-terminate the string". Besides, it's a character literal, so it's also lit up by visual assist. It's also the same length as "null". Aside from anticonformist originality, I fail to see how NULL would have any advantage over the idiomatic, time-tested version.

Quote:But this is for a PIC, I can't imagine that you'd care so much about safety that you'd sacrifice all that time doing strlen and malloc ... maybe some kind of stack alloc function would be a compromise?


*Snicker* Sacrifice? My, what a big nasty word. If concatenating strings is so essential to the performance of a program that one or two strlen and malloc will cause such immense problems, then the original poster would be better off looking for better solutions than a generic concatenation function. My first reflex would be to get std::string going, which would save the strlen and malloc times for good (it stores its length and can have custom allocators and COW) far better than a handcrafted solution. Also look into PHP's ob_start, which is quite nifty if you handle it wel, whenever you need multiple concatenations.

In the end though, the main question is: how high is the performance/productivity ratio of string manipulation in your program? In short, why do you want to spend 10 hours increasing performance by 0.01% in a seldom-executed part of your program? The fundamental rule when optimizing a program is simple : write clean and safe code first, then profile, and optimize code where it will have the most effect.

Consider this slightly exaggerated parable: Ann spends 10 hours building a clean, safe and unoptimized string-manipulation program in C, then 30 hours profiling and optimizing the relevant parts. Ben, on the other hand ,spends 30 hours building a carefully hand-optimized C-string manipulation system, and 10 hours getting it to work because of the bugs introduced by higher intellectual complexity.

Assume that both Ann and Ben optimize at the same speed (which can be doubted, since Ben would have to write his code at the same time). We'll assume that every hour Ann and Bob spend on a line of code increases that line's performance by 100% of its initial performance.

Ann optimized the 20% of code that is run 80% of the time. That's 30 hours times 100% per line, so the performance gain is 0.8 * 3000 + 0.2 * 100 = 2420%.

Ben optimized 100% of the code. That's 30 hours times 100% per line, but Ben worked on five times as many lines as Ann, so where Ann spent 30 hours, Ben only spent only 6. So, the performance gain is only 600%. To get the same effect as Ann, Ben would have to work four times as much, or 120 hours of optimization.
You can only program pics in c.

Well with the offical Complier anyway.

Quote:Original post by Anonymous Poster
You can only program pics in c.

Well with the offical Complier anyway.


WTF are you talking about? What official compiler and what PICs? I could use my own custom language to program PICs if I wanted to. Since most languages are turing-complete; assuming they have access to the same low-level facilities, you should be able to convert any piece of language code into C or the PIC's machine code.

EDIT: Are you the original author making a statement about your specific PIC and the tools you have access to?
Most PIC microcontrollers have about 3.5k of Program Memory, and 128 bytes(yes bytes) of ram, with Clock of 20Mhz.


They have a speicial type of ASM language with about 20 Commands, and thats it.

Running c++ would be stupid.


I should know i study electronics.

You usually program them with official MPLAB ide and program adapter, in assembly and then pay extra for the c18 offical complier.

They don't have a c++ complier.

Unless you would like to write one?
What i'm trying to say is ASM, and C are the only languages officially supported.

and I really need to log in to the forum.
Quote:Original post by ToohrVyk
Quote:Original post by Inmate2993
strncat( name, first, sizeof(name)-1 );strncat( name, last, sizeof(name)-1 );
...
int len = strlen(first) + strlen(last);char *name = malloc(len + 1);strncpy(name, first, len);strncat(name, last, len);name[len] = '\0'; 

Both of those are using strncat wrongly: the third parameter is the maximum number of characters to copy from the source - it's not the maximum length of the destination. It doesn't matter in ToohrVyk's code since the buffer is guaranteed to be long enough (and in that case strcpy/strcat would work just as well, and there's no need to set the last character to 0 anyway because strncat guarantees that); but in general, strncat doesn't do what any sane person would want it to do.

VC2005's strcat_s does do the sane thing (taking the size of the destination buffer as an argument), so it seems quite sensible to write your own version of that.
Quote:Original post by Excors
VC2005's strcat_s does do the sane thing (taking the size of the destination buffer as an argument), so it seems quite sensible to write your own version of that.


You're right, I was thinking of strcat_s as well. Serves me right for not using C string manipulation often enough. Although, now that I look at it, it seems that strncat doesn't null-terminate the output if it overflows.
Quote:Original post by ToohrVyk
it seems that strncat doesn't null-terminate the output if it overflows.

They say "The strncat() function appends up to n characters from string s2 to string s1, and then appends a terminating null character" and "A terminating null byte is always appended to the result".

But, oddly, the online MSDN says "strncat only adds a trailing NULL if there is room left in the buffer, strDest" but that's totally impossible because it has no idea how much space is left in the buffer. The offline documentation from VS2005 says "The all cases [sic], the resulting string is terminated with a null character", which agrees with everybody else and with VS2005's CRT source code (since it does an unconditional *front = '\0'; at the end of strncat). So MSDN seems surprisingly wrong.

Edit: Oh, that's the Windows CE 5.0 version. At least one of the many other pages documenting the same function says the right thing.

Quote:Serves me right for not using C string manipulation often enough.
I think "never" is the optimum frequency at which to use C string manipulation [smile]

This topic is closed to new replies.

Advertisement