* Some question about one method. @ 2004-05-21 10:24 Alphex Kaanoken 2004-05-21 21:17 ` Jan-Benedict Glaw 0 siblings, 1 reply; 9+ messages in thread From: Alphex Kaanoken @ 2004-05-21 10:24 UTC (permalink / raw) To: Linux devellist Hi guys, I'm have a some question how I can change the: sprintf(tmp,"%s%c",tmp,sym); where - char *tmp;int sym; may I use strcat or another method. I need a fast and better method for do it. Thanx. -- Senior Developer of Crew IT research labs Alphex Kaanoken <alphex@crew.org.ru> Web: http://crew.org.ru ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-21 10:24 Some question about one method Alphex Kaanoken @ 2004-05-21 21:17 ` Jan-Benedict Glaw 2004-05-24 8:06 ` Charlie Gordon 0 siblings, 1 reply; 9+ messages in thread From: Jan-Benedict Glaw @ 2004-05-21 21:17 UTC (permalink / raw) To: Linux devellist [-- Attachment #1: Type: text/plain, Size: 899 bytes --] On Fri, 2004-05-21 14:24:41 +0400, Alphex Kaanoken <alphex@crew.org.ru> wrote in message <1085135081.21344.21.camel@relay.localnet>: > Hi guys, > I'm have a some question > how I can change the: > sprintf(tmp,"%s%c",tmp,sym); > where - char *tmp;int sym; > may I use strcat or another method. > I need a fast and better method for do it. That's perfectly good in C. Why do you want to change that? It the length of ths ASCIIZ string pointed to by temp is known, there's a good chance to optimize it. However, that's against readability, so I'd advise against it. MfG, JBG -- Jan-Benedict Glaw jbglaw@lug-owl.de . +49-172-7608481 "Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg fuer einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA)); [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-21 21:17 ` Jan-Benedict Glaw @ 2004-05-24 8:06 ` Charlie Gordon 2004-05-24 17:30 ` Jan-Benedict Glaw 0 siblings, 1 reply; 9+ messages in thread From: Charlie Gordon @ 2004-05-24 8:06 UTC (permalink / raw) To: linux-c-programming On Fri, 2004-05-21 14:24:41 +0400, Alphex Kaanoken <alphex@crew.org.ru> wrote in message <1085135081.21344.21.camel@relay.localnet>: > Hi guys, > I'm have a some question > how I can change the: > sprintf(tmp,"%s%c",tmp,sym); > where - char *tmp;int sym; > may I use strcat or another method. > I need a fast and better method for do it. Jan-Benedict Glaw commented: > That's perfectly good in C. Why do you want to change that? It the > length of ths ASCIIZ string pointed to by temp is known, there's a good > chance to optimize it. However, that's against readability, so I'd > advise against it... I must disagree : this piece of code is NOT perfectly good in C. 1) sprintf is a nest of buffer overflow bugs waiting to bite. The issue is of course the size of the tmp buffer. If it is known, the code can be optimized and that will not make it less readable, conversely, if it is not known, then we have a real bug in front of us, as extending the string by one character will likely overwrite whatever is next in memory. Don't use sprintf ! use snprintf. If you cannot use snprintf, then you are in trouble. 2) assuming you can use the destination buffer as an argument to sprintf is asking for trouble ! Obviously it would almost certainly fail if not used as the first argument for a format string starting with %s : a very restrictive case. ISO-C is very clear about such an abuse: 7.19.6.6 Description "...If copying takes place between objects that overlap, the behavior is undefined." A C library that would not support it and modify tmp before it is used as the source for %s would not be incorrect. The unsuspecting C newbie (and the vast majority of his elders) would not understand why sprintf(tmp,"%s%c",tmp,sym); would "work" and sprintf(tmp,"%c%s",sym,tmp); would "fail". Do not encourage such ugly code. If you know tmp will accomodate the extra character, why not use the following code: char *p = tmp + strlen(tmp); p[0] = sym; p[1] = '\0'; Or better, if you know tmp size: int len = strlen(tmp); if (len + 1 < tmp_size) { tmp[len++] = sym; tmp[len] = '\0'; } // notice how len is still the length of the tmp string. Lastly, if you do not understand the above code snipplets, you are lacking some fundamental C concepts esp. pointers and should not undertake any significant programming project in C. This is just friendly advice, as debugging it will be horribly frustrating. JBG's concern about readability would be best addressed with a utility function, possibly implemented inline such as: char *strncat1(char *buf, int bufsize, int c); Chqrlie. PS: a few simple trick questions for C newbies : - what is -1 ? - what is wrong with : enum BOOL { FALSE=0, TRUE=1 }; - what is the difference between : i << 2 and i * 4 - same question for : i >> 2 and i / 4 ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-24 8:06 ` Charlie Gordon @ 2004-05-24 17:30 ` Jan-Benedict Glaw 2004-05-24 23:24 ` Charlie Gordon 0 siblings, 1 reply; 9+ messages in thread From: Jan-Benedict Glaw @ 2004-05-24 17:30 UTC (permalink / raw) To: linux-c-programming [-- Attachment #1: Type: text/plain, Size: 4015 bytes --] On Mon, 2004-05-24 10:06:51 +0200, Charlie Gordon <gmane@chqrlie.org> wrote in message <c8sab1$biq$1@sea.gmane.org>: > On Fri, 2004-05-21 14:24:41 +0400, Alphex Kaanoken <alphex@crew.org.ru> > wrote in message <1085135081.21344.21.camel@relay.localnet>: > > Hi guys, > > I'm have a some question > > how I can change the: > > sprintf(tmp,"%s%c",tmp,sym); > > where - char *tmp;int sym; > > may I use strcat or another method. > > I need a fast and better method for do it. > > Jan-Benedict Glaw commented: > > That's perfectly good in C. Why do you want to change that? It the > > length of ths ASCIIZ string pointed to by temp is known, there's a good > > chance to optimize it. However, that's against readability, so I'd > > advise against it... > > I must disagree : this piece of code is NOT perfectly good in C. > > 1) sprintf is a nest of buffer overflow bugs waiting to bite. The issue is > of course the size of the tmp buffer. If it is known, the code can be > optimized and that will not make it less readable, conversely, if it is not > known, then we have a real bug in front of us, as extending the string by > one character will likely overwrite whatever is next in memory. > Don't use sprintf ! use snprintf. If you cannot use snprintf, then you are > in trouble. There are sane uses of sprintf(). C is (and always was) by experts for experts. So you've to do proper allocation anyways:) > 2) assuming you can use the destination buffer as an argument to sprintf is > asking for trouble ! Obviously it would almost certainly fail if not used > as the first argument for a format string starting with %s : a very Argh, you're right on this one. I didn't catch it :-( > restrictive case. ISO-C is very clear about such an abuse: 7.19.6.6 > Description "...If copying takes place between objects that overlap, the > behavior is undefined." A C library that would not support it and modify > tmp before it is used as the source for %s would not be incorrect. The > unsuspecting C newbie (and the vast majority of his elders) would not > understand why sprintf(tmp,"%s%c",tmp,sym); would "work" and > sprintf(tmp,"%c%s",sym,tmp); would "fail". > Do not encourage such ugly code. I don't - I'm totally against it now that I've seen that. I never ever came to the idea of using a source string for destination... [code fragments] > Lastly, if you do not understand the above code snipplets, you are lacking > some fundamental C concepts esp. pointers and should not undertake any > significant programming project in C. This is just friendly advice, as > debugging it will be horribly frustrating. I second that. C's syntax is quite simple, but only people who really understand C's pointer and allocation concepts should use it. > JBG's concern about readability would be best addressed with a utility > function, possibly implemented inline such as: > > char *strncat1(char *buf, int bufsize, int c); Right:) > - what is -1 ? > - what is wrong with : enum BOOL { FALSE=0, TRUE=1 }; > - what is the difference between : i << 2 and i * 4 > - same question for : i >> 2 and i / 4 That's mostly sign problems/questions. (I don't think there's something technically wrong with the enum BOOL, but you shouldn't use it except with other enum BOOL xxx variables ...). But more interestingly: char *a; short *b; int *c; long *d; long long *e; --> What's the difference between a++ and e++? struct { char first; char second; } s1; struct { char both[2]; } s2; What's the difference:) But to come to an end, I haven't seen the abous of tmp in the given example... MfG, JBG -- Jan-Benedict Glaw jbglaw@lug-owl.de . +49-172-7608481 "Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg fuer einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA)); [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-24 17:30 ` Jan-Benedict Glaw @ 2004-05-24 23:24 ` Charlie Gordon 2004-05-25 0:06 ` Jeff Woods 2004-05-25 0:41 ` Glynn Clements 0 siblings, 2 replies; 9+ messages in thread From: Charlie Gordon @ 2004-05-24 23:24 UTC (permalink / raw) To: linux-c-programming Hi JBG, > There are sane uses of sprintf()... There is almost no overhead to using snprintf. And it is so difficult to prove that a given sprintf format cannot overflow... Just try this one: what if ints are 64 bits now, is the buffer large enough to accomodate all these digits ? Yet there is much worse function : strncpy. This sucker does NOT do what you think it does. Pull the man page, read it, read it again... unbelievable isn't it ? Test it, grep any source files for this buddy, I bet you'll find subtle bugs stuck to it like fly paper. > C is (and always was) by experts for experts. > C's syntax is quite simple, but only people who really > understand C's pointer and allocation concepts should use it. I agree completely on this, programming in C is like riding down the guardrail, except it's more like a razor blade. It's just so hard to always keep a sharp eye for all the pitfalls one comes across in even the simplest one liners. I urge you to get a look at http://www.joelonsoftware.com/ I especially like his "Guerrilla Guide to Interviewing" (http://www.joelonsoftware.com/articles/fog0000000073.html) : "I've discovered that understanding pointers in C is not a skill, it's an aptitude. For some reason most people seem to be born without the part of the brain that understands pointers. This is an aptitude thing, not a skill thing - it requires a complex form of doubly-indirected thinking that some people just can't do." >> - what is wrong with : enum BOOL { FALSE=0, TRUE=1 }; > (I don't think there's something technically wrong with the enum > BOOL, but you shouldn't use it except with other enum BOOL > xxx variables ...) Well you are going to love this one! defining BOOLeans TRUE and FALSE as an enum makes them available for symbolic debugging, but you should still #define them to avoid nasty surprises with the preprocessor: #if TRUE // if you don't, this code will never compile #endif > char *a; > short *b; > int *c; > long *d; > long long *e; > > --> What's the difference between a++ and e++? it makes them point to the next element in the arrays of respective types, and as such increments the binary value by a different amount. More interestingly what is the difference between e[5] and 5[e] ? > struct { > char first; > char second; > } s1; > struct { > char both[2]; > } s2; > what's the difference ? On most architectures, not much. But C makes no guaranties as to the actual layout of structures. In particular (&s1.second - &s1.first) may be different than 1. Similarly sizeof(s1) can be different from sizeof(s2). Glad you found my quiz useful. Chqrlie. PS:) did you know about this new C library extension : imprecations you can pass extra information to some of the C runtime APIs, thus preventing some of the most annoying problems in C. for example, memory allocation issues are finally solved : p = malloc(n), "nofail"; free(p), "pack"; p = realloc(p, newsize), "nomove"; best of all, your compiler most likely already supports imprecations ;-) ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-24 23:24 ` Charlie Gordon @ 2004-05-25 0:06 ` Jeff Woods 2004-05-25 0:41 ` Glynn Clements 1 sibling, 0 replies; 9+ messages in thread From: Jeff Woods @ 2004-05-25 0:06 UTC (permalink / raw) To: Charlie Gordon; +Cc: linux-c-programming At 5/25/2004 01:24 AM +0200, Charlie Gordon wrote: >>char *a; >>short *b; >>int *c; >>long *d; >>long long *e; >> >>--> What's the difference between a++ and e++? > >it makes them point to the next element in the arrays of respective types, >and as such increments the binary value by a different amount. > >More interestingly what is the difference between e[5] and 5[e] ? Since pointer addition is commutative [i.e., *(e+5) == *(5+e) ] they're the same thing. My favorite C obfuscation. (And I only use it when I intend to be obtuse! :) Note below that "j" is an int and "t" is an array of char and there's a "putchar(j[t])" in there. [Yes, it compiles and runs.] -- int main(void){int j=2003;/*(c)2003 cishikawa.*/ char t[]="+<WJ> @abcdefghijklmnopqrstuvwxyz.,\n\""; char*i="y>b<+x,m+tie@.juswndnc@dt<Wupi\"JWhysbJirviiy"; while(*i)((j+=strchr(t,*i++)-(int)t),(j%=sizeof t-1), (putchar(j[t])));return 0;}/* under GPL */ ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-24 23:24 ` Charlie Gordon 2004-05-25 0:06 ` Jeff Woods @ 2004-05-25 0:41 ` Glynn Clements 1 sibling, 0 replies; 9+ messages in thread From: Glynn Clements @ 2004-05-25 0:41 UTC (permalink / raw) To: Charlie Gordon; +Cc: linux-c-programming Charlie Gordon wrote: > > struct { > > char first; > > char second; > > } s1; > > struct { > > char both[2]; > > } s2; > > what's the difference ? > > On most architectures, not much. But C makes no guaranties as to the actual > layout of structures. > In particular (&s1.second - &s1.first) may be different than 1. More generally, (&s1.second - &s1.first) is meaningless. Pointer arithmetic is only defined when both pointers refer to elements of a common array. -- Glynn Clements <glynn.clements@virgin.net> ^ permalink raw reply [flat|nested] 9+ messages in thread
* RE: Some question about one method. @ 2004-05-21 10:54 Ranga Reddy M - CTD ,Chennai. 2004-05-21 21:19 ` Jan-Benedict Glaw 0 siblings, 1 reply; 9+ messages in thread From: Ranga Reddy M - CTD ,Chennai. @ 2004-05-21 10:54 UTC (permalink / raw) To: Alphex Kaanoken, Linux devellist Hi, char ch[1]; ch[0]=(char) sym; ch[1]='\0'; strcat(tmp,ch); usage of the strcat as you mentioned. But, how fast this is going to be I have no idea. Cheers, Ranga -----Original Message----- From: Alphex Kaanoken [mailto:alphex@crew.org.ru] Sent: Friday, May 21, 2004 3:55 PM To: Linux devellist Subject: Some question about one method. Hi guys, I'm have a some question how I can change the: sprintf(tmp,"%s%c",tmp,sym); where - char *tmp;int sym; may I use strcat or another method. I need a fast and better method for do it. Thanx. -- Senior Developer of Crew IT research labs Alphex Kaanoken <alphex@crew.org.ru> Web: http://crew.org.ru - To unsubscribe from this list: send the line "unsubscribe linux-c-programming" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html ^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Some question about one method. 2004-05-21 10:54 Ranga Reddy M - CTD ,Chennai. @ 2004-05-21 21:19 ` Jan-Benedict Glaw 0 siblings, 0 replies; 9+ messages in thread From: Jan-Benedict Glaw @ 2004-05-21 21:19 UTC (permalink / raw) To: Linux devellist [-- Attachment #1: Type: text/plain, Size: 1080 bytes --] On Fri, 2004-05-21 16:24:23 +0530, Ranga Reddy M - CTD ,Chennai. <rangareddym@ctd.hcltech.com> wrote in message <53BBBB3235C2C74583722B212B36CA0D61F909@vishnu.ctd.hcltech.com>: > Hi, > > char ch[1]; > ch[0]=(char) sym; > ch[1]='\0'; > > strcat(tmp,ch); > > usage of the strcat as you mentioned. > But, how fast this is going to be I have no idea. Whoops, off by one! That's a bad (read as wrong and possibly even a security relevant bug). You declared "ch" to be an array with one element, that's ch[0]. So you're not allowed to assign anything to ch[1]. If you need two bytes, just ask for that. Remember, inside the braces you put number of elements. It's not the highest useable index (which is one less than number of elements). MfG, JBG -- Jan-Benedict Glaw jbglaw@lug-owl.de . +49-172-7608481 "Eine Freie Meinung in einem Freien Kopf | Gegen Zensur | Gegen Krieg fuer einen Freien Staat voll Freier Bürger" | im Internet! | im Irak! ret = do_actions((curr | FREE_SPEECH) & ~(NEW_COPYRIGHT_LAW | DRM | TCPA)); [-- Attachment #2: Digital signature --] [-- Type: application/pgp-signature, Size: 189 bytes --] ^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-05-25 0:41 UTC | newest] Thread overview: 9+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2004-05-21 10:24 Some question about one method Alphex Kaanoken 2004-05-21 21:17 ` Jan-Benedict Glaw 2004-05-24 8:06 ` Charlie Gordon 2004-05-24 17:30 ` Jan-Benedict Glaw 2004-05-24 23:24 ` Charlie Gordon 2004-05-25 0:06 ` Jeff Woods 2004-05-25 0:41 ` Glynn Clements -- strict thread matches above, loose matches on Subject: below -- 2004-05-21 10:54 Ranga Reddy M - CTD ,Chennai. 2004-05-21 21:19 ` Jan-Benedict Glaw
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).