So you can still compile and run old crappy code.Originally Posted by Thantos
Quzah.
So you can still compile and run old crappy code.Originally Posted by Thantos
Quzah.
Hope is the first step on the road to disappointment.
It should be a compile time error with a message like:Or something like thatWhat the hell are you thinking using gets(). Don't you know that the devil himself will raise up by using this function? Begone heathen!
It should just delete the file you're compiling.Originally Posted by Thantos
Quzah.
Hope is the first step on the road to disappointment.
Wow,
This function must be hated world-wide I'll be sure to never use it, even if bribed with the most amount of money immaginable. fgets() forever!
- Stack Overflow
Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.
I am not disagreeing with strrchr being safe and reasonable, but I do have a few comments on it being the fastest.Originally Posted by Stack Overflow
The call to strrchr may need to start at the beginning of the string, look for the null terminator, and then begin the backwards search for the newline. If it's there, you'll find it right away. If it isn't there, you'll have to go all the way back to the beginning of the string before it returns NULL.
Using strchr might be slow as well, because it looks for the newline and it looks for the terminating null for each character from beginning to the end.
When immedaitely following a call to fgets, the newline (if it is there) will be at the end right before the terminating null. Now since we know that the newline will only be at the end, why not just look there? Call strlen, back up one, and look for a newline. If it is there, replace it with a null.
This is a comparison thingy I'd written a while ago.Code:#include <stdio.h> #include <string.h> #include <time.h> char *foo(char *s) { size_t len = strlen(s); char *newline = s + len - 1; if ( *newline == '\n' ) { *newline = '\0'; } return s; } char *bar(char *s) { char *newline = strrchr(s, '\n'); if ( newline ) { *newline = '\0'; } return s; } char *baz(char *s) { char *newline = strchr(s, '\n'); if ( newline ) { *newline = '\0'; } return s; } char *qux(char *s) { strtok(s, "\n"); return s; } char *zed(char *s) { size_t newline = strlen(s) - 1; if ( s [ newline ] == '\n' ) { s [ newline ] = '\0'; } return s; } #define BIND(j) {j,#j} int main(void) { static const struct { char *(*call)(char*); const char *name; } function[] = { BIND(foo), BIND(bar), BIND(baz), BIND(qux), BIND(zed) }; char text[][45] = {/* 01234567890123456789012345678901234567890123 */ "All work and no play makes Jack a dull boy!\n", "The quick brown fox jumps over the lazy dog.", }; size_t i,j,k; for ( i = 0; i < sizeof text / sizeof *text; ++i ) { for ( j = 0; j < sizeof function / sizeof *function; ++j ) { clock_t end, start; start = clock(); for ( k = 0; k < 50000000; ++k ) { text[0][43] = '\n'; function[j].call(text[i]); } end = clock(); printf("%s: %g, \"%s\"\n", function[j].name, (end - start) / (double)CLOCKS_PER_SEC, function[j].call(text[i])); fflush(stdout); } putchar('\n'); } return 0; } /* my output foo: 3.055, "All work and no play makes Jack a dull boy!" bar: 3.835, "All work and no play makes Jack a dull boy!" baz: 8.102, "All work and no play makes Jack a dull boy!" qux: 16.884, "All work and no play makes Jack a dull boy!" zed: 3.075, "All work and no play makes Jack a dull boy!" foo: 3.174, "The quick brown fox jumps over the lazy dog." bar: 9.654, "The quick brown fox jumps over the lazy dog." baz: 8.202, "The quick brown fox jumps over the lazy dog." qux: 17.014, "The quick brown fox jumps over the lazy dog." zed: 3.105, "The quick brown fox jumps over the lazy dog." */
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
Naturally, your mileage may vary...
In my case, both times, strrchr is the fastest implementation.foo: 13.16, "All work and no play makes Jack a dull boy!"
bar: 10.46, "All work and no play makes Jack a dull boy!"
baz: 10.84, "All work and no play makes Jack a dull boy!"
qux: 27.84, "All work and no play makes Jack a dull boy!"
zed: 12.87, "All work and no play makes Jack a dull boy!"
foo: 12.88, "The quick brown fox jumps over the lazy dog."
bar: 9.98, "The quick brown fox jumps over the lazy dog."
baz: 10.69, "The quick brown fox jumps over the lazy dog."
qux: 27.98, "The quick brown fox jumps over the lazy dog."
zed: 12.49, "The quick brown fox jumps over the lazy dog."
gcc (GCC) 3.2.3 (Debian)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Quzah.
Hope is the first step on the road to disappointment.
>>strrchr is the fastest implementation
You really care about speed when processing a single line of user input?!
My "method of the moment" is to strtok() it. OK, it may be more of an overhead, but it saves typing, and shortens my source, and doesn't require validation (of course the fgets() call does though).
>>strtok(input, "\n");
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Well,
I do know for a fact:
Sure is alot faster and safer than:Code:if ((c = strrchr(sentence, '\n'))) *c = '\0';
Or, at least I know that much now.Code:sentence[strlen(sentence) - 1] = '\0';
- Stack Overflow
Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.
The problem with that though is if the string has a length of 0 you will be working with an invalid index (-1).char *foo(char *s)
{
size_t len = strlen(s);
char *newline = s + len - 1;
if ( *newline == '\n' )
{
*newline = '\0';
}
return s;
}
Code:#include <cmath> #include <complex> bool euler_flip(bool value) { return std::pow ( std::complex<float>(std::exp(1.0)), std::complex<float>(0, 1) * std::complex<float>(std::atan(1.0) *(1 << (value + 2))) ).real() < 0; }
Ah,
Yes I see that now. I never got the chance to try it but yeah -1 is an invalid index I believe. How does this implementation look, does it contain any flaws or is it any faster than strrchr() itself?
Code:char* jar(const char *, int); char* har(const char *, int); int main() { char *c; char sentence[25] = "Testing\n"; char sentence2[15] = "Testing\n"; if (c = jar(sentence, '\n')) *c = '\0'; if (c = har(sentence2, '\n')) *c = '\0'; return 0; } char* jar(const char *string, int c) { char *s, cc = c; char *sp = (char *)0; s = (char *)string; while (*s) { if (*s == cc) sp = s; s++; } if (cc == 0) sp = s; return sp; } char* har(const char *string, int c) { char *pch = 0; while( *string ) { if( *string == c ) pch = (char *)string; string++; } return (char *)pch; }
Thank you for your time,
- Stack Overflow
Last edited by Stack Overflow; 07-06-2004 at 06:01 PM.
Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.
Nice catch on that one. Because it is perfectly legal to use the function like so:Originally Posted by Sebastiani
Code:foo( "" );
Which interestingly enough, gives me the following output, in addition to the above:
It doesn't crash though. So at least that's good. Oddly in this case, strchr beats strrchr.foo: 3.32, ""
bar: 1.7, ""
baz: 1.44, ""
qux: 4.08, ""
zed: 2.27, ""
Quzah.
Hope is the first step on the road to disappointment.
Originally Posted by Dave_SinkulaI was aware of that. I just hadn't come up with a way of having fgets not return NULL but have an empty string, although I guess I hadn't tried passing it a 1-character "string". An empty line, "\n", will be 1 character long.Originally Posted by Sebastiani
Last edited by Dave_Sinkula; 07-06-2004 at 08:19 PM. Reason: "a empty string" -> "an empty string"
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
>>foo( "" );
>>It doesn't crash though. So at least that's good.
Lucky more like Modifying string literals is a no no.
@Stack Overflow: If all you're looking for is a quick way to terminate a string at the first occurence of a particular character (which is what the "strip newline" type functions you've created do), try this:
Code:#include <stdio.h> void foo(char *s, int c) { while (*s && *s != c) { s++; } *s = '\0'; } int main(void) { char n[] = "blahh\n"; char m[] = "\n"; printf("n after >%s<\n", n); foo(n, '\n'); printf("n after >%s<\n", n); printf("m before >%s<\n", m); foo(m, '\n'); printf("m after >%s<\n", m); return(0); }
When all else fails, read the instructions.
If you're posting code, use code tags: [code] /* insert code here */ [/code]
Wow,
That looks cool. Thanks again, and it looks just like what I needed. (I think)
Well, this topic has saved me lots of time trying to remove that '\n' out of my sentence. Can't believe I didn't think about a simple 5 liner code:
And simple too!Code:void foo(char *s, int c) { while (*s && *s != c) s++; *s = '\0'; }
Thanks all for your help,
- Stack Overflow
Last edited by Stack Overflow; 07-07-2004 at 05:38 PM.
Segmentation Fault: I am an error in which a running program attempts to access memory not allocated to it and core dumps with a segmentation violation error. This is often caused by improper usage of pointers, attempts to access a non-existent or read-only physical memory address, re-use of memory if freed within the same scope, de-referencing a null pointer, or (in C) inadvertently using a non-pointer variable as a pointer.
Actually I'd modified the example to have another line in the array of text being passed it so it had a string like that.Originally Posted by Hammer
Quzah.Code:char text[][45] = {/* 01234567890123456789012345678901234567890123 */ "All work and no play makes Jack a dull boy!\n", "The quick brown fox jumps over the lazy dog.", "", };
Hope is the first step on the road to disappointment.