Skip to main content
gamedev.net
🔒 Locked

Damn C code

Started by Trashcann Jul 19, 2003 at 10:43 PM 22 replies 1.7k views
Original Post
Trashcann
Trashcann
Why doesnt this work? /* test string.C */ #include <string.h> int main() { string sbuf; /* error here- undeclared identifyer some sh** like that */ reuturn 0; }
ermokwww.truevision3d.com
Psybr
Psybr
(In C++?) you have to add the line "using namespace std;" or type std::string.
Trashcann
Trashcann
ok, i put that first comment in there to indicate it was C AND the subject says damn C code- i know how this works in c++ buts its pissed at me when i do it with GCC
and it gets pissed at me when i use #include <string> using namespace std;

either way it gets pissed
ermokwww.truevision3d.com
Trashcann
Trashcann
really? so whats the equivilant of it? or, is there a way to declare a char with a dynamic length so it will be whatever length you put into it? how do you pro''s do that? (like, say, what a person says in a chat thing on a MMORPG)
ermokwww.truevision3d.com
Way Walker
Way Walker
quote:
Original post by Trashcann
Why doesnt this work?

/* test string.C */

#include <string.h>

int main() {
string sbuf; /* error here- undeclared identifyer some
sh** like that */
reuturn 0;
}



As pointed out, there is no string class in C (no classes at all in C, for that matter). What you use in C is just a plain old array of characters.

As for creating string of any length, there are two ways.

1)
char myString[] = "My String";

2)
char *myString = malloc(strlen("My String") + 1);
strcpy(myString, "My String");

The first only works if you don''t want to ever put a string in that array that is longer than strlen("My String") + 1. The second you can use realloc to change the size of the string.

Can this be a pain? Yes. Can this be error prone? Yes. Are other languages better suited to string processing? Yes. So why not use one of them? Because C might be just what you need every where else and interfacing with another language isn''t worth the effort for how much string processing you''re doing.
Trashcann
Trashcann
hmm makes sense- thanks a bunch dude. is this any different in c++? (besides the string class) is C even OOP?
ermokwww.truevision3d.com
Way Walker
Way Walker
quote:
Original post by Anonymous Poster
These are valid C strings:
char myString[16] = "Hey Ima String!";
char* anutherString = "Yo!";

I don''t think there even is a string.h (I mean that comes with the compilter and is considered a standard include) for C. So yeah, in C you treat a string as a character array.


There is a string.h and it includes many useful functions. It includes some memory manipulation functions (memcpy, memcmp, etc.) and string manipulation functions (strcpy, strcmp, strchr, strstr, etc.)

Also note that your last line would be better written as

const char *anutherString = "Yo!";

because you can''t portably write to a string constant.
cowsarenotevil
cowsarenotevil
C is not OO, use G++ instead. Or you could make a linked list of chars instead... but why write your own data structures when there already is one for strings.
-~-The Cow of Darkness-~-
Trashcann
Trashcann
is there a diff. between
char* mychar = "YO";
and
char *mychar = "YO";
ermokwww.truevision3d.com
Way Walker
Way Walker
quote:
Original post by Trashcann
hmm makes sense- thanks a bunch dude. is this any different in c++? (besides the string class) is C even OOP?


This is very different from what you would do in C++. In C++ you''d use the string class (as others have suggested) which does all the malloc/realloc''ing for you and has a few more functions than are in C''s string.h (cstring for C++). Of course, you can do it the C way in C++ if you like, but I''d recommend using the string class unless you have some good reason not to (performance of your implementation''s string class, for instance). (Note that I prefer C, but when in Rome...)

As for the OOP-ness of C, it''s not. The closest you can get is not giving the users of your library the internals of your struct/union. (i.e. all they get is a line saying "struct MyStruct" and a bunch of functions that work on "struct MyStruct"''s) It does not provide inheritance or polymorprism without a decent amount of extra work on the coder''s part. However, you can program in an OO manner in C. Good examples are probably gtk and the win32 API. OO in C generally involves callbacks and ADT''s (created as mentioned above).
cowsarenotevil
cowsarenotevil
quote:
Original post by Trashcann
is there a diff. between
char* mychar = "YO";
and
char *mychar = "YO";


No, but I''m not sure using a pointer without "newing" it is such a good idea. You''re basically writing that to random memory as far as I can tell (though I could be wrong).
-~-The Cow of Darkness-~-
Trashcann
Trashcann
When exactly do you USE a pointer? i know how to declare them but why and when and where use them?
ermokwww.truevision3d.com
cowsarenotevil
cowsarenotevil
Use them for dynamic allocation of memory. You can create a class with a pointer to an instance of itself as a pointer(so it doesn''t take up an infinite amount of memory ''till you "new" it) and then write a recursive function to write to the children (and grandchildren, etc. ) and you have a (rather crude) dynamic linked list.

(pseudocode)

class thingy
{
thingy * child;
}
-~-The Cow of Darkness-~-
Trashcann
Trashcann
im sorry im very new and that made very little sense- talk to me like im stupid lol
ermokwww.truevision3d.com
Way Walker
Way Walker
quote:
cowsarenotevil
C is not OO, use G++ instead. Or you could make a linked list of chars instead... but why write your own data structures when there already is one for strings.



Probably just being nitpicky, but a linked list of chars is not considered a string in C.

There are also valid reasons to write your own. One would be that it''s a learning experience. Another would be that you have a known implementation with known behavior. For instance, let''s say better performance is required, and you can get better performance using your special knowledge of the current problem?

Or let''s even say you have to use C (C++ not ported to your platform, C++ compilers on your platform are crap, are dealing with legacy C code, your boss pays you for C but not C++, etc.) The only data structure C has for strings is a NUL-terminated array of char. Perhaps a struct containing an array of char and the length of the string would work better in your case? "However," you say, "others have created such string libraries, why not use one of those?" Licensing issues, perhaps? Not ported to your platform? Not-Invented-Here-Syndrome? You judge that keeping the style consistent provides larger gains than a short loss of productivity?


quote:
Trashcann
is there a diff. between
char* mychar = "YO";
and
char *mychar = "YO";


As far as the compiler is concerned, there is no difference. I prefer the second style for two reasons. The first (and more controversial) reason is that the first style can create confusion in the following code

char* c1, c2;

which is the same as

char* c1;
char c2;

This is controversial, because nearly everyone agrees that you shouldn''t mix pointers and non-pointers in the same declaration. A slightly smaller group says that you shouldn''t have more than one declaration per line.

The other reason is the idea of "declaration mimics use" which C tends to follow. You declare a pointer to a char the same way you''d use a pointer to a char. That is, you''d type

*myChar

to use the char, so you declare it by typing

char *myChar
cowsarenotevil
cowsarenotevil
I never said that a linked list of chars was "considered" a string, I just said that it was an alternative to the C++ string class.
-~-The Cow of Darkness-~-
Trashcann
Trashcann
i also prefer the second one, so GO US!
ermokwww.truevision3d.com
Way Walker
Way Walker
quote:
cowsarenotevil
quote:
Trashcann
is there a diff. between
char* mychar = "YO";
and
char *mychar = "YO";



No, but I''m not sure using a pointer without "newing" it is such a good idea. You''re basically writing that to random memory as far as I can tell (though I could be wrong).



It''s not writing anything to random memory, but it is creating a pointer into what is potentially read-only memory. A string constant is a pointer to a char, but not one that you can write to. It''s not a pointer to a const char because that would break old code (I''m not sure why it wasn''t originally a pointer to const char, maybe in the pre-K&R days it was common to be able to write to a string constant?)

What would most definitely be a bad idea without using new/malloc would be

strcpy(mychar, "YO");

that would write to random memory.


quote:
Trashcann
When exactly do you USE a pointer? i know how to declare them but why and when and where use them?



There are two reasons to use them. One is that you use them when you have to. The other is when you''re passing a large data structure into a function. Both of these been have largely (but not entirely) replaced by references in C++, but we''re talking about C here, right?

When do you have to use them? When you need to dynamically allocate memory (i.e. get memory at runtime) or when you need to pass an object to be modified by a function (i.e. simulate pass-by-reference symantics).

Dynamic memory is the stuff that you get from malloc, realloc, and calloc. You have to call free on the pointer when you''re done with it. These are used when you need a place to store something (a string perhaps) but don''t know the size at runtime. Let''s say you''re getting a string from the user. You don''t know how long it''s going to be at compile time, so you have to use malloc/realloc in a loop with fgets. (Note, this is why you should not use gets. It doesn''t ask for the size of the buffer so, if the user types in more characters than you have space for, it just keeps writing and creates a buffer-overflow.)

As for modifying an object in a function, let''s say you have something like this:

int main(void) {
int a = 1;
f(a);
printf("%d ", a);
g(&a);
printf("%d\n", a);
}
void f(int b) { b++; }
void g(int *b) { (*b)++; }

This should print out "1 2". This is because a copy of "a" was passed to f(), but a pointer to "a" was passed to g() (actually, a copy of a pointer to "a". Hence we''re simulating pass-by-reference by passing a pointer by value).

This idea of copying the variable before it gets to the function is why it''s more efficient to pass a pointer to a large object to a function than it is to pass a large object to a function. A pointer is (on many platforms) as large as an int, which is relatively small. An object can be much larger than an int, at which point allocating the memory and copying the object into that memory can become significant.
Way Walker
Way Walker
quote:
Original post by cowsarenotevil
I never said that a linked list of chars was "considered" a string, I just said that it was an alternative to the C++ string class.


I see, I assumed you were talking about C, where the interfaces are quite different. My appologies for the misunderstanding.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.