Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Smackbilly
Jan 3, 2001
What kind of a name is Pizza Organ! anyway?

more falafel please posted:

The biggest problem people generally have with learning pointers is that they're told "oh yeah, pointers are hard, that's why I hate C," and then they believe it's some horrible convoluted thing.

Agreed. Pointers are hard to avoid making mistakes with (memory leaks, etc). They aren't hard to understand. A lot of new programmers don't pick up on that distinction when some people bitch about pointer problems.

Adbot
ADBOT LOVES YOU

Thug Bonnet
Sep 22, 2004

anime tits ftw

Smackbilly posted:

Agreed. Pointers are hard to avoid making mistakes with (memory leaks, etc). They aren't hard to understand. A lot of new programmers don't pick up on that distinction when some people bitch about pointer problems.

Well to be fair if your first language isn't strongly-typed and you come to C later on it can get hairy and that may trickle down to pointers, too. Also, the concept of pass-by-reference versus pass-by-value is more obfuscated in other weakly(okay fine, "dynamically")-typed languages, though in essence I think it's the same issue. People think pointers are difficult (I thought so too), but the trick is they are simple, just deceptively so.

TSDK
Nov 24, 2003

I got a wooden uploading this one

chutwig posted:

Just telling somebody to read K&R again doesn't help much when dealing with something like pointers that is very complex.
Well chapter 5 is one of the best and most concise explanations of pointers, so it is well worth giving it another read. It's certainly a much better explanation than anything I could have typed in response.

Zombywuf
Mar 29, 2008

more falafel please posted:

The biggest problem people generally have with learning pointers is that they're told "oh yeah, pointers are hard, that's why I hate C," and then they believe it's some horrible convoluted thing.

Yeah, I do wonder how many problems could be solved with:
code:
#define new(type) (((type) *)malloc(sizeof(type)))
#define newa(type, size) (((type) *)malloc(sizeof(type) * (size)))
Those defines almost make C look like Java and D-flat. Adding | sed -e 's/Segmentation fault/NullPointerException/' 2>&1 to the end of the command line should get rid of most of the rest of the confusion :-).

TSDK
Nov 24, 2003

I got a wooden uploading this one

Zombywuf posted:

Yeah, I do wonder how many problems could be solved with:
Probably not as many as you'd cause. It's bad form in C to cast the result of malloc, because of the rules on implicit declarations for functions. Putting those casts would suppress compile errors caused by missing header file includes and cause a linker error.

deadjb
Aug 11, 2002

I'm working on a fixed point class, which looks kind of like this:

code:
class cFp
{
    // constructors, copy, assignment
    cFp();
    cFp(const cFp& copy);
    operator=(const cFp& rhs);

    // cast from other types
    cFp(int i);
    cFp(float f);

    // casting operators
    operator int();
    operator float();

    // arithmetic operators
    inline cFp& operator+=(const cFp& rhs) { /*add stuff*/ }
}

inline cFp operator+(const cFp& lhs, const cFp& rhs)
{
    cFp result = lhs;
    result += rhs;
    return result;
}
I have some simple stupid test code like this:

code:
cFp f = 3;
cFp g = cFp(0.45676f);

f + g;
f += g;
f += 2;.

2 += f;
f + 2;
2 + f;
The first group of operations (up to and including f += 2) work fine. However, I'm getting ambiguous operator overload errors with the next 3. I can understand how (2 += f) wouldn't work, but I'm confused why the next 2 don't. Afterall, (f += 2) works fine, and that's used by my (+) operator.

Why doesn't this work, and is there a way to resolve these ambiguities without explicitly casting ints and floas to cFp objects? I'm afraid it will require listing a new operator overload for each primitive type I want to use, but I'm hoping there's an easier, cleaner way.

deadjb fucked around with this message at 15:42 on Jun 13, 2008

Mikey-San
Nov 3, 2005

I'm Edith Head!

TSDK posted:

Well chapter 5 is one of the best and most concise explanations of pointers, so it is well worth giving it another read. It's certainly a much better explanation than anything I could have typed in response.

100% agreed. Pointers were a problem for me until I read chapter 5 of K&R carefully, not moving to the next example until I understood the previous one completely. When I finished, all ambiguity and confusion was gone, and I haven't had a problem since.

TSDK
Nov 24, 2003

I got a wooden uploading this one
The compiler doesn't know whether you want to implicitly convert 2 to a cFp, or f to an int.

Get rid of those user defined cast operators in cFp and replace them with:
code:
    // casting operators
    int as_int() const { return ...; }
    float as_float() const { return ...; }

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I could be wrong about this because C++ overload resolution rules are really loving confusing, but here's what I think:

It's because you have an implicit cast from int, so it can't tell whether to use +(int, int) or +(cFp, cFp). (I believe the += works because it's a member of the cFp class and not just a related function.) If you add an "explicit" keyword to your constructors, it should fix this problem at the cost of making you say, "cFp f = cFp(3)" instead of "cFp f = 3".

ISTR Alexandrescu having a chapter about this issue.

EDIT: now that I see it I think TSDK's right, it's because you have both an implicit cast to int and an implicit constructor from it. One or the other should work but not both.

deadjb
Aug 11, 2002

JoeNotCharles, TSDK posted:

advice

Ah, yeah, I completely understand now. Thank you both of you.

I really, really like this thread. I hope I can be of more help in the future.

Edit: I removed the casting operators (changing them to the AsInt/AsFloat methods), but I get a problem with (f+2). The error is "error: no match for 'operator+' in 'f + 2'". Shouldn't this work now, because 2 should be treated as a cFp?

deadjb fucked around with this message at 16:15 on Jun 13, 2008

deadjb
Aug 11, 2002

I pasted my code to Nopaste. It's templated code, because I want to have varying precision and internal types. Additionally, I have a #define to create the binary arithmetic operators, because it's a lot of repeated code that doesn't really change save for which operators are being made.

At the bottom of the file is my main function, with a simple typedef to avoid repeated template parameters. I added the error messages in the appropriate lines of the main function.

http://rafb.net/p/RrIa7B42.html


vvvvvvvvvv Thanks, I've cleaned that up in my local now.

deadjb fucked around with this message at 20:24 on Jun 13, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
One thing: inside cFixedPoint, don't type cFixedPoint<Storage, LongStorage, kPrecision>, it's not necessary. Just the name is sufficient; the compiler will deduce the template parameters.

EDIT: As for your problem, the compiler isn't going to be able to deduce the type of a template if both arguments ("f" and "2") aren't of the appropriate type (cFixedPoint in this case). If you want to allow addition of literals, you'll need operator overloads for them. Boost's enable_if will simplify this for you.

Avenging Dentist fucked around with this message at 20:27 on Jun 13, 2008

deadjb
Aug 11, 2002

Avenging Dentist posted:

One thing: inside cFixedPoint, don't type cFixedPoint<Storage, LongStorage, kPrecision>, it's not necessary. Just the name is sufficient; the compiler will deduce the template parameters.

EDIT: As for your problem, the compiler isn't going to be able to deduce the type of a template if both arguments ("f" and "2") aren't of the appropriate type (cFixedPoint in this case). If you want to allow addition of literals, you'll need operator overloads for them. Boost's enable_if will simplify this for you.

I thought C++ supported automatic promotion if there exists a constructor which takes the type you're promoting from as its only parameter?

EDIT: At least, that's what I believe this is claiming (down in the "Overloading binary operators" section), is it not?:

http://oopweb.com/CPP/Documents/CPPAnnotations/Volume/cplusplus09.html

deadjb fucked around with this message at 20:32 on Jun 13, 2008

Avenging Dentist
Oct 1, 2005

oh my god is that a circular saw that does not go in my mouth aaaaagh
It doesn't work for templated operators, since the template instantiation occurs before type promotion does, and without type promotion, the proper template instantiation can't be chosen.

deadjb
Aug 11, 2002

Alright, I understand. I took a look through enable_if, and while I understand it, for now I'm going to just do some #define-ing. I don't really like to use #define, but it should make it pretty straightforward to read the interface.

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

Smackbilly posted:

Agreed. Pointers are hard to avoid making mistakes with (memory leaks, etc). They aren't hard to understand. A lot of new programmers don't pick up on that distinction when some people bitch about pointer problems.

I figured out my earlier stupidity. Obviously, I came from Java. :v: It was also good to get some experience working with valgrind and MallocDebug to see that I'm managing memory properly now and mallocing/freeing in the right places. Doing it correctly also helps enforce the difference between statically allocating memory on the stack and dynamically allocating it from the heap.

In my own experience, the fundamental notion of a pointer is not hard. It's a variable that stores a memory address. Most of my confusion originates in what I perceive to be counterintuitive syntax by C. When you write something like char *blah, if you're reading it left to right, you initially think it's a variable of type char, and then have to reset mentally and re-read it as a pointer pointing to something of type char. I feel that syntax such as "&char blah", which could be read "address-of-char", would have been a more intuitive way to declare a pointer. The fact that * both declares and dereferences pointers is likewise confusing and is only overcome after you spend a while working with the language. I'm sure most of you will disagree with me, but that's just how I feel about these particular operators; that they were chosen for their roles somewhat haphazardly and inconsistently.

That being said, I am now having another runabout with C, this time in printing out pieces of my earlier struct. Consider the following gdb output:
code:
(gdb) print curr_q
$1 = (active_query_t *) 0x80b14a8
(gdb) print curr_q->current_query
$2 = (GString *) 0x80a7f20
(gdb) print curr_q->current_query->str
$3 = (gchar *) 0x80b14f8 "<IDLE>"
(gdb) print curr_q->current_query->len
$4 = 6
(gdb) print curr_q->current_query->allocated_len
$5 = 16
Everything looks okay, right? I can access the members, read everything, it all looks good, no problem.

code:
(gdb) call printf("%s", curr_q->current_query->str)
$6 = 6
(gdb) call printf("%s", curr_q)
<IDLE
$7 = 6
:raise:

code:
(gdb) call printf("%i", curr_q->current_query->len)
$8 = 1
:ssj:

If only I understood your mysteries, C. I discovered this initially because invoking printf within the program with something like
code:
printf ("%i | %i | %s\n", curr_q->datid, curr_q->procpid, curr_q->current_query->str);
causes an immediate segfault in strlen (if you remove all string values, everything else prints fine).

This seems to be the case with all the GStrings in the struct; if you call printf within gdb and ask it to print the actual null-terminated string out, it prints out the integer value of len instead. If you ask it to print the integer value of len out, you always get 1. If you ask for it as a string value, the program then segfaults in the debugger. What's going on here? Here's a sample of the code that sets up the GString (I know it sucks, but it's the only way I could devise in which I could actually free the PGresult after I was done with it without causing a crash, and I didn't try to optimize it at all once I figured out a way).

code:
char *current_query_str = (char *) malloc (1 + PQgetlength (db_activity, i, PQfnumber (db_activity, "current_query")) * sizeof (char));
strcpy (current_query_str, PQgetvalue (db_activity, i, PQfnumber (db_activity, "current_query")));
curr_q->current_query = g_string_new (current_query_str);
free (current_query_str);
This code may not be the best, but thus far it works and causes no memory leaks (if the struct is no longer used, the GStrings are freed by a destructor function called by the hash table). Everything was fine until I tried to print a string out. The field is documented as being publicly accessible and treatable as a regular null-terminated C string, so it's not like I'm not doing anything bad printing it out this way.

Allie
Jan 17, 2004

I'm pretty sure that value gdb prints each time is the return value of the function. printf doesn't return a string, it returns the amount of characters it wrote (an int). You probably aren't seeing it actually print anything because you aren't including a newline, so stdout isn't getting flushed.

Also, it probably doesn't make sense to print curr_q as a string since it looks like its first member isn't a string. You should be using the proper data types in your format strings. %i (or more commonly, %d) refers to a signed integer.

Basically, you need to read the documentation for the libraries you're using, including glib's documentation and the standard library documentation for your distribution. You also might want to read gdb's documentation. :)

Incoherence
May 22, 2004

POYO AND TEAR

chutwig posted:

Most of my confusion originates in what I perceive to be counterintuitive syntax by C. When you write something like char *blah, if you're reading it left to right, you initially think it's a variable of type char, and then have to reset mentally and re-read it as a pointer pointing to something of type char. I feel that syntax such as "&char blah", which could be read "address-of-char", would have been a more intuitive way to declare a pointer.
This is the motivation behind the use of char* blah, since it makes it more obvious that blah is of type pointer-to-char instead of char. The only reason it's not more prevalent is that if you type char* a, b, c;, a is a pointer, but b and c are not.

And yes, the overloading of the * operator is fairly obnoxious, but then again I could say the same about the . operator in Java.

slovach
Oct 6, 2005
Lennie Fuckin' Briscoe
One more GDI question.

I seem to be getting horrible flickering when I blit something ontop of another, for instance a mask for transparency to a picture, and then the actual picture. It works fine, I just get really bad flickering, which I guess makes sense.

How do I avoid this?

If anyone cares, source and example: http://dykebeard.drinkhound.com/porn/starfield.rar

edit: Yeah, I suck cocks. I want double buffering. Somehow it took all day to think of blitting the whole thing at once, only to find out that is double buffering. :downs:

slovach fucked around with this message at 04:19 on Jun 14, 2008

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

Milde posted:

Basically, you need to read the documentation for the libraries you're using, including glib's documentation and the standard library documentation for your distribution. You also might want to read gdb's documentation. :)

That's great, except notwithstanding that I forgot printf's return type due to my inexperience, it still doesn't explain why saying
code:
printf("%s\n", curr_q->current_query->str)
would crash in the code but not in the debugger. I'm not sure why you're telling me printing curr_q isn't relevant, because at no point do I actually print it n the code. print looks like printf, but is the same command as inspect in gdb.

chutwig fucked around with this message at 03:13 on Jun 14, 2008

Allie
Jan 17, 2004

You should read the documentation for something if you aren't familiar with it or haven't used it in a while. Man pages will describe return values. If you're using a function and it's returning something that doesn't make any sense to you, it's probably a good idea to review the documentation before you jump to conclusions.

Your second example calls printf without newlines, which means the output won't necessarily show up in your console immediately. And the second call to printf passes curr_q as a string, even though it's a struct. I wasn't commenting on your first example, and I said it doesn't make sense to print the struct as a string, not that it's irrelevant.

I don't know why you're getting different results in and out of the debugger, but sometimes it is possible for this to happen. Were those debugger commands run postmortem? Have you tried loading the core dump the program generated when it crashed?

If you're really absolutely stumped, I recommend running valgrind on your program. It might reveal the source of the problem, or reveal that something else is indirectly causing the crash. Turning on all/extra warnings in your compiler might also help.

Allie fucked around with this message at 04:38 on Jun 14, 2008

vanjalolz
Oct 31, 2006

Ha Ha Ha HaHa Ha
What happens if you printf(curr_q->current_query->str) directly?

Smackbilly
Jan 3, 2001
What kind of a name is Pizza Organ! anyway?

chutwig posted:

That's great, except notwithstanding that I forgot printf's return type due to my inexperience, it still doesn't explain why saying
code:
printf("%s\n", curr_q->current_query->str)
would crash in the code but not in the debugger. I'm not sure why you're telling me printing curr_q isn't relevant, because at no point do I actually print it n the code. print looks like printf, but is the same command as inspect in gdb.

My first thought with this bug would be that the string that you're printing is not null terminated. In GDB the block that you malloc might be set to all nulls, whereas at runtime it may not be.

Try using memset to set your string to all NULs right after you malloc it, and see if the problem goes away. If so, double check your sizes and string copy operations to see where you're writing one too many characters into the string.

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

Smackbilly posted:

My first thought with this bug would be that the string that you're printing is not null terminated. In GDB the block that you malloc might be set to all nulls, whereas at runtime it may not be.

The str segment in a GString is null-terminated, so it's usable as a valid C string. In the course of my learning about malloc, I was initially mallocing the GString as well as using g_string_new on it, but that turned out to be a double malloc, so I was leaking memory every time I did that. The way I'm handling it now, with g_string_new and then g_string_free if I'm deleting the struct from the hash table, seems to be the correct way to handle things.

vanjalolz posted:

What happens if you printf(curr_q->current_query->str) directly

If I puts it by itself, no problem. If I printf it by itself, even, again, no problem. Only when I try to print it together with other non-string variables does it explode like this. That would explain why I wasn't having the problem in the debugger, because I wasn't doing the exact same thing. Now that I'm trying the exact same thing:
code:
(gdb) call (int)printf("%i | %s\n", curr_q->datid, curr_q->current_query->str)
11511 | (null)
$1 = 15
(gdb) call (int)printf("%s\n", curr_q->current_query->str)
<IDLE>
$2 = 7
(gdb) call (int)printf("%i | %s\n", curr_q->datid, curr_q->backend_start->str)
11511 | (null)
$3 = 15
(gdb) call (int)printf("%s\n", curr_q->backend_start->str)
2008-06-14 14:47:54
$4 = 20
(gdb) call (int)printf("%s | %s\n", curr_q->current_query->str, curr_q->backend_start->str)
<IDLE> | 2008-06-14 14:47:54
$5 = 29
So apparently it's null when printed with something else that isn't a string, but prints in all other situations.

That being said, I can solve this pretty easily by either just printing them separately, or using a regular char* instead of a GString. Any thoughts on what might cause this behavior? I'm using OS X right now, but I first noticed the behavior on Linux. Since I'm on OS X right now, I don't have access to valgrind, but I do have MallocDebug (which does the same thing as memcheck), and there's no memory being leaked anywhere.

chutwig fucked around with this message at 20:10 on Jun 14, 2008

vanjalolz
Oct 31, 2006

Ha Ha Ha HaHa Ha
Not sure, maybe GStrings aren't 8 byte characters or something. I had problems with %s before, no idea how I fixed it.

Try sprintf perhaps.

ani47
Jul 25, 2007
+

chutwig posted:

code:
(gdb) call (int)printf("%i | %s\n", curr_q->datid, curr_q->current_query->str)
11511 | (null)
$1 = 15
(gdb) call (int)printf("%s\n", curr_q->current_query->str)
<IDLE>
$2 = 7
(gdb) call (int)printf("%i | %s\n", curr_q->datid, curr_q->backend_start->str)
11511 | (null)
$3 = 15
(gdb) call (int)printf("%s\n", curr_q->backend_start->str)
2008-06-14 14:47:54
$4 = 20
(gdb) call (int)printf("%s | %s\n", curr_q->current_query->str, curr_q->backend_start->str)
<IDLE> | 2008-06-14 14:47:54
$5 = 29

It looks to me that curr_q->datid isnt a 4byte integer (probably 8) and its remaining top bytes are being used for the %s argument (which would be the NULL).

Test:

code:
int blah = (int)curr_q->datid;
printf("%i | %s\n", blah, curr_q->current_query->str)
Instead of %i use the 64bit version for your compiler (%ll for gcc? - I have no idea).

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

ani47 posted:

It looks to me that curr_q->datid isnt a 4byte integer (probably 8) and its remaining top bytes are being used for the %s argument (which would be the NULL).

Test:

code:
int blah = (int)curr_q->datid;
printf("%i | %s\n", blah, curr_q->current_query->str)
Instead of %i use the 64bit version for your compiler (%ll for gcc? - I have no idea).

Yeah, that actually occurred to me this morning, but since I'm currently babysitting some Exchange 2007 service pack updates I haven't had a chance to try it and see what happens. It would make sense, though.

Spug
Dec 10, 2006

Then turn not pale, beloved snail, but come and join the dance.

chutwig posted:

Most of my confusion originates in what I perceive to be counterintuitive syntax by C. When you write something like char *blah, if you're reading it left to right, you initially think it's a variable of type char, and then have to reset mentally and re-read it as a pointer pointing to something of type char.

Incoherence posted:

This is the motivation behind the use of char* blah, since it makes it more obvious that blah is of type pointer-to-char instead of char. The only reason it's not more prevalent is that if you type char* a, b, c;, a is a pointer, but b and c are not.

I think K&R says that it's supposed to be a mnemonic. In char *b = 'R';, *b is kind of defined to "return" a char.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I've been pouring over git tutorials and I can't find the answer to a simple question:

I've made changes to several files in a directory, but not added them to the index yet because I'm just screwing around. I decide that the changes to about half the files are crap, and I want to throw them away (revert them to the version in the index). How do I do this?

All I can find is "git reset --hard HEAD" which reverts both the index and working dir, and only works on whole directories at a time, and "git reset --mixed HEAD", which makes the index match the working tree. I can't figure out how to do the opposite of --mixed.

Lexical Unit
Sep 16, 2003

I'm by no means a git expert but I use it for personal projects sometimes. In the past I've simply used git checkout to "unedit" (BitKeeper terminology) files. However it appears there are better options: http://bryan-murdock.blogspot.com/2007/07/git-revert-is-not-equivalent-to-svn.html

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

Lexical Unit posted:

I'm by no means a git expert but I use it for personal projects sometimes. In the past I've simply used git checkout to "unedit" (BitKeeper terminology) files. However it appears there are better options: http://bryan-murdock.blogspot.com/2007/07/git-revert-is-not-equivalent-to-svn.html

code:
$ git checkout -f WebKit.pro
git checkout: updating paths is incompatible with switching branches/forcing
Did you intend to checkout 'WebKit.pro' which can not be resolved as commit?
What??

That link just says to use "git reset --hard HEAD", which doesn't work because it blows away changes to the index file too, and doesn't take a list of file:

code:
$ git reset --hard HEAD WebKit.pro
Cannot do partial --hard reset.
I think git checkout is what I want, but what the hell is that error message?

floWenoL
Oct 23, 2002

JoeNotCharles posted:

code:
[code]
$ git reset --hard HEAD WebKit.pro
Cannot do partial --hard reset.
I think git checkout is what I want, but what the hell is that error message?

You can do a partial checkin and then a hard reset:

code:
git add -i
<interactively pick which chunks to check in>
git commit
git reset --hard

ShoulderDaemon
Oct 9, 2003
support goon fund
Taco Defender

JoeNotCharles posted:

code:
$ git checkout -f WebKit.pro
git checkout: updating paths is incompatible with switching branches/forcing
Did you intend to checkout 'WebKit.pro' which can not be resolved as commit?
What??

That link just says to use "git reset --hard HEAD", which doesn't work because it blows away changes to the index file too, and doesn't take a list of file:

code:
$ git reset --hard HEAD WebKit.pro
Cannot do partial --hard reset.
I think git checkout is what I want, but what the hell is that error message?

You want to use git checkout without the -f, as explained in the comments of that link and the error message you got.

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

floWenoL posted:

You can do a partial checkin and then a hard reset:

code:
git add -i
<interactively pick which chunks to check in>
git commit
git reset --hard

That doesn't help if I've got a bunch of stuff that's not ready to commit, and a bunch of stuff which is definitely garbage. I guess the git way is to make a "not ready to commit" branch and check all the stuff that's not ready in anyway.

ShoulderDaemon posted:

You want to use git checkout without the -f, as explained in the comments of that link and the error message you got.

Aha, I skimmed over the second paragraph of the man page and just saw "-f: This is used to throw away local changes". Thanks, that's just what I wanted!

MagneticWombats
Aug 19, 2004
JUMP!
I'm working with ncurses and I'm having a problem with getch().

I have a loop that sort of looks like:
code:
while (TRUE)
{
   start=time_right_now();
   i=getch();
   if(i==BLAHLBAH)
     dosomething1();
   if(i==BLASHLE2)
     dosomething2();
   current=time_right_now();
   while((current-start)<somenumber)
   {
     current=time_right_now();
   }
}
Essentially, it's a game loop that only allows one action every somenumber. The problem is, if I hold down say "a", the character "a" gets stuck in a buffer somewhere so even after I let go of "a" there are a bunch of "a"s sticking around in the buffer which are read into getch() seconds, maybe even minutes (if I held down "a" realllly long) after I let go of the letter "a". Now one solution I've thought up of is to clear the buffer somehow after every successful getch(). I'm using raw() and halfdelay(1) if that's any help. I googled around and the best answers I've gotten included mucking with ASM (because people apparently only used ncurses in 1996). I thought about using a dedicated game library but I'd like to think there was a simple solution using ncurses.

MagneticWombats fucked around with this message at 08:51 on Jun 17, 2008

chglcu
May 17, 2007

I'm so bored with the USA.

mofmog posted:

code:
while (TRUE)
{
   start=time_right_now();
   i=getch();
   if(i==BLAHLBAH)
     dosomething1();
   if(i==BLASHLE2)
     dosomething2();
   current=time_right_now();
   while((current-start)<somenumber)
   {
     current=time_right_now();
   }
}

I think you need to have your calls to getch() not be effected by your delay. I don't know anything about ncurses, so there might be other alternatives, but you could try something along these lines:

code:
start=time_right_now();
while (TRUE)
{
   i=getch();
   if((time_right_now()-start)>=somenumber)
   {
      if(i==BLAHLBAH)
        dosomething1();
      if(i==BLASHLE2)
        dosomething2();
      start=time_right_now();
   }
}
As long as your dosomething*()s don't take longer than the keyboard repeat rate, I think that should work.

FearIt
Mar 11, 2007
Is there an easy way to execute another program from c++?

Basically I'm trying to begin execution of programs in my c:\program files\.. through my program.

An example opening notepad.exe from its pathname instead of just calling system(notepad) would be great!

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

FearIt posted:

Is there an easy way to execute another program from c++?

Basically I'm trying to begin execution of programs in my c:\program files\.. through my program.

An example opening notepad.exe from its pathname instead of just calling system(notepad) would be great!

On Windows, CreateProcess or CreateProcessEx. I'm not sure if the second one is preferred over the first or just has some extra options.

On Mac and Linux, fork followed by exec.

FearIt
Mar 11, 2007

JoeNotCharles posted:

On Windows, CreateProcess or CreateProcessEx. I'm not sure if the second one is preferred over the first or just has some extra options.

On Mac and Linux, fork followed by exec.

I'm having trouble understanding all the arguements is there anyway I could get an example of CreateProcess?

Adbot
ADBOT LOVES YOU

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

FearIt posted:

I'm having trouble understanding all the arguements is there anyway I could get an example of CreateProcess?

Have you tried Googling "CreateProcess example"?

(I highly recommend avoiding the Windows API as much as possible and using higher-level libraries like .NET or Qt, since in almost all cases the API is so much better that you'll save hours and hours of headache in exchange for an extra half hour of setup time. CreateProcess is one of the prime examples. In Qt you'd use the QProcess class for this, for instance. But if you've already started something changing to a new language or framework for this one feature doesn't make any sense.)

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply