View Full Version : The new FAQ
Hammer
02-18-2003, 08:15 AM
I've been working on a new format FAQ, which you can view here (http://faq.cprogramming.com/).
I've used most of the content from Lightatdawn's FAQ, taken some stuff from the FAQ board, and written some of my own. I'll add more in due course. If there's anything specific you'd like to see in there, let me know. If you want to write anything yourself, feel free to do so, ask me for details on how to submit it.
All comments/suggestions/corrections are welcome, either reply to this thread or PM me.
Enjoy. :)
Nice job, hopefully it sees more use than the old one. I don't like the logo though :P
edit: i think the vc++ series should be in the compiler/ide section, i was suprised that it is not.
geez Hammer... you're all involved in the community and making it better now... what gives? ;)
seriously... looks good. Keep up the superb work, my friend.
This got bumped down b4 it got seen, maybe sticky it? well....bumpety...
Hammer
02-18-2003, 06:23 PM
>>hopefully it sees more use than the old one
I can but hope that newbies read it :D
>>I don't like the logo though
Yah well... it ain't that bad. I couldn't do too much in a 100x100 image. Still, this is about the FAQ itself, not the logo :)
>>involved in the community, what gives
Well, yonks ago I said I'd do this, so I thought I'd better keep my promise. :cool:
[edit]Stickied for a day or two
Travis Dane
02-18-2003, 06:23 PM
Looks good...For beginners that is, I now have to click 2 links to
get to my answer!
Yeah, I know, I'm a lazy bump:p
-KEN-
02-18-2003, 06:58 PM
Woohoo, my submission is up! Looks like we'll have to stop our late-night submission sodomizations, l@d :eek:
golfinguy4
02-18-2003, 07:03 PM
Do you want me to do a C++ Style converting int to string?
BTW, it looks nice.
#include <sstream> //this header automatically includes iostream and is needed for ostringstream
#include <string>
using namespace std;
string IntToString(int num); //this will be our converter function
int main(void)
{ int number=5;
string result=IntToString(number);
cout<<result<<endl;
cin.get();
return 0;
}
string IntToString(int num)
{ ostringstream myStream; //creates an ostringstream object
myStream<<num<<flush;
/*outputs the number into the string stream and then flushes
the buffer (makes sure the output is put into the stream)*/
return myStream.str(); //returns the string form of the stringstream object
}
Hammer
02-18-2003, 07:31 PM
>>Do you want me to do a C++ Style converting int to string?
Sure :) Help is welcome.
If anyone wants to submit anything for this, here's a few guidelines:
The code must be:
- valid, ie it compiles and does what its supposed to
- standard. Don't use things like getch() when there is no need
- not over complicated for target audience.
- documented. Try to put some decription text with your code. This is an FAQ afterall, not a snippets library.
As for the formatting, just submit it to me in text, I'll sort out the HTML to go round it.
[edit]
Thanks golfinguy4, I see you've posted some code. I'll sort that out later. I'm going to be off in a minute :o
Eibro
02-18-2003, 08:41 PM
Use this if you'd like...
If you want, i'll write some more tommorow.
Why does my program enter an infinite loop if the user inputs invalid data?
Suppose you prompt the user to enter an integer value, and they enter something like "foo" or 'q'. Your istream-derived object (usually cin) attempts to extract an integral value from the input buffer, fails, and all subsequent input attempts fail.
To remedy this, you must check your object for a fail state after extraction, flush the input buffer, and attempt another extraction.
using std::cout;
using std::cin;
// ...
int input = 0;
while (cout << "Enter a number: " && !(cin >> input))
{
cout << "\nInvalid input\n";
cin.clear();
cin.ignore(std::numeric_limits<int>::max());
}
Output
Enter a number: Hello
Invalid input
Enter a number: d
Invalid input
Enter a number: 2
Note: If you're unfamiliar with the funky std::numeric_limits<int>::max() statement, it's equivalent to the INT_MAX macro in <climits> or <limits.h>. Basically, it descripts the largest value an integer can hold. Include <limits> to use the std::numeric_limits template.
std::endl vs. '\n'
It's simple, std::endl sends a '\n' and flushes the output buffer. '\n' does not flush the output buffer.
How can I get input without having the user hit <enter>?
Using standard C/C++, you cannot. However, if you're lucky your compiler may have the non-standard conio.h header (which includes getch()), if you're on *nix (UNIX, Linux, etc.) you can try the ncurses library, else try the different API input routines (such as those included in the Win32 API)
Hammer
02-19-2003, 04:43 AM
Thanks Eibro. I'll have a proper look at this tonight and put it up.
deathstryke
02-21-2003, 08:51 AM
I'm having trouble figuring out the section on unbuffered input. May be I just need to learn a little more before I try, but it seems so much more useful than cin.
It might prove more effective to simplify the code (maybe even as far as something like saying to press enter and then spitting out whether they did or not, in this case). Complexity leads to confusion.
Hammer
02-21-2003, 02:49 PM
@deathstryke: Are you meaning this (http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1045691686&id=1043284392) entry? I'll write something easier to understand if so. :)
Eibro
02-21-2003, 10:29 PM
I'm going to write some more once I get some time.
A fix to "Why does my program enter an infinite loop..."; below the code where I mention the std::numeric_limits<int> template, '<int>' is being treated as an HTML tag and it's not showing up.
Edit:
How can I convert a char/string to upper or lower case?
For single characters converting to upper/lower case is simple, use the functions toupper() and tolower() included in ctype.h or cctype.
For example:
#include <cctype>
#include <iostream>
int main(int argc, char** argv)
{
using std::cout;
using std::toupper;
using std::tolower;
char letter = 'a';
cout << "Before toupper: " << letter << endl;
letter = toupper(letter);
cout << "After toupper: " << letter << endl;
letter = tolower(letter);
cout << "After tolower: " << letter << endl;
return 0;
}
/*
Output:
Before toupper: a
After toupper: A
After tolower: a
*/
For strings, it's a little more compilcated.
First, it depends on what type of 'string' you're using. If it's traditional c-style strings (character arrays) then you'll need to iterate through the array and call tolower or toupper for each element.
#include <cctype>
#include <iostream>
int main(int argc, char** argv)
{
using std::cout;
using std::endl;
char hello[] = "Hello World";
cout << "Before conversion: " << hello << endl;
for (char* iter = hello; *iter != '\0'; ++iter)
{
*iter = std::tolower(*iter);
++iter;
}
cout << "After conversion: " << hello << endl;
return 0;
}
/*
Output:
Before conversion: Hello World
After conversion: hello world
*/
For C++-style strings of the std::string type, things are essentially the same. You need to iterate through each character and call tolower or toupper. Luckily, the STL includes an algorithm which does most of the work for us.
#include <algorithm>
#include <string>
#include <iostream>
#include <cctype>
int main(int argc, char** argv)
{
using std::string;
using std::cout;
using std::endl;
string hello = "Hello World";
cout << "Before conversion: " << hello << endl;
std::transform(hello.begin(), hello.end(), hello.begin(), std::tolower);
return 0;
}
/*
Output:
Same as above example
*/
Edit again: I'm unsure whether tolower and toupper are in namespace std. VC6 doesn't seem to think so, but that compiler is far from standards compliant.
Sebastiani
02-22-2003, 02:43 AM
For the todo list: :)
A sample directory walker:
/*
Note: your compiler may require preceding underscores for some of the functions/constants/data structures used here.
ie: _findfirst or _A_SUBDIR, etc...
*/
#include <dirent.h>
#include <string.h>
#include <iostream>
static char CURRENT_DIRECTORY[1024];
void
Search(const char * folder, const char * substring)
{
DIR * directory = opendir(folder);
if(directory == NULL) return;
chdir(folder);
finddata_t * file = &directory->dd_dta;
long index = findfirst("*", file);
do
{
if(strstr(file->name, substring))
{
if(file->attrib & A_SUBDIR)
cout << " Folder:" << endl;
else
cout << " File:" << endl;
if(file->attrib & A_ARCH)
cout << "(Archive)" << endl;
if(file->attrib & A_SYSTEM)
cout << "(System)" << endl;
if(file->attrib & A_HIDDEN)
cout << "(Hidden)" << endl;
if(file->attrib & A_RDONLY)
cout << "(Read Only)" << endl;
getcwd(CURRENT_DIRECTORY, 1024);
cout << CURRENT_DIRECTORY << "\\" << file->name << endl;
}
if(file->attrib & A_SUBDIR
&& strcmp(file->name, ".") != 0
&& strcmp(file->name, "..") != 0)
{
Search(file->name, substring);
chdir("..");
}
} while(findnext(index, file) == 0);
findclose(index);
closedir(directory);
return;
}
int main()
{
Search("c:\\", "config.sys");
cout << endl << "Finished Searching.";
cin.get();
}
A simple busy wait function:
#include <time.h>
void wait(unsigned milliseconds)
{
unsigned timeout = clock() + milliseconds;
while( clock() < timeout ) continue;
}
Two handy functions for newbies:
void say(const char * str, ...)
{
char quote[strlen(str)+1024];
va_list v;
va_start(v, str);
vsprintf(quote, str, v);
int length = strlen(quote);
if(length && length < 80)
{
if(length%2)
++length;
for(int i = 0; i < 40-length/2; ++i)
cout << " ";
cout << quote << endl;
}
cin.get();
}
void affirm(bool condition)
{
if(condition)
say("Yes.");
else
say("No.");
}
int main()
{
int x = 4096;
affirm(x > 4095);
}
in a reply to eibro, this following codeline will compile in vc++
std::transform(userInput.begin(), userInput.end(), userInput.begin(), tolower);
(not that my variable name is diff because its from another program)
Hammer
02-22-2003, 06:02 PM
Thanks again everyone. I'll put these up soon. :)
Sebastiani
02-23-2003, 02:36 PM
Some more for the todo list, possibly. :D
/*
A simple class derived from the time.h 'struct tm'.
I used a similar class to write a time-clock program.
A class like this is very useful for compactly
storing/retrieving time info from files, BTW.
For instance, 1000 dates can be stored in a binary file
of only 4K (assuming 4-byte time_t storage).
TODO:
Only localtime() support was added.
Expand as necessary.
*/
class Time : tm {
public:
Time(struct tm& time);
Time(time_t time);
Time();
void second(int set);
void minute(int set);
void military_hour(int set); // 0-23
void hour(int set, bool pm = false);
void day(int set);
void yearday(int set); // 0-364
void weekday(int set); // 0-6
void month(int set);
void year(int set);
int second() const;
int minute() const;
int military_hour() const;
int hour() const;
int day() const;
int yearday() const;
int weekday() const;
int month() const;
int year() const;
time_t time();
operator time_t () // implicit conversion, very useful.
{
return time();
}
time_t now(); // set to the current time.
time_t set(time_t time);
time_t set(struct tm& time);
double difference(time_t other);
time_t operator = (struct tm& time);
time_t operator = (time_t time);
bool operator == (time_t other);
bool operator > (time_t other);
bool operator < (time_t other);
const char * printable(); // beware: returns a static buffer!
};
/* The Implementation: */
Time::Time(struct tm& time)
{
set(time);
}
Time::Time(time_t time)
{
set(time);
}
Time::Time()
{
now();
}
void Time::second(int set)
{
tm_sec = set;
}
int Time::second() const
{
return tm_sec;
}
void Time::minute(int set)
{
tm_min = set;
}
int Time::minute() const
{
return tm_min;
}
void Time::military_hour(int set)
{
tm_hour = set;
}
int Time::military_hour() const
{
return tm_hour;
}
void Time::hour(int set, bool pm = false)
{
if(set < 12 && pm == true)
{
set += 12;
}
else if((set == 24) || (set == 12 && pm == false))
{
set = 0;
}
military_hour(set);
}
int Time::hour() const
{
int hr = military_hour();
if(hr == 0)
hr = 12;
else if(hr > 12)
hr -= 12;
return hr;
}
void Time::day(int set)
{
tm_mday = set;
}
int Time::day() const
{
return tm_mday;
}
void Time::yearday(int set)
{
tm_yday = set;
}
int Time::yearday() const
{
return tm_yday;
}
void Time::weekday(int set)
{
tm_wday = set;
}
int Time::weekday() const
{
return tm_wday;
}
void Time::month(int set)
{
tm_mon = set-1;
}
int Time::month() const
{
return tm_mon+1;
}
void Time::year(int set)
{
tm_year = set-1900;
}
int Time::year() const
{
return tm_year+1900;
}
time_t Time::time()
{
return std::mktime(this);
}
time_t Time::now()
{
return set(std::time(NULL));
}
time_t Time::set(time_t time)
{
struct tm * record = std::localtime(&time);
if(record)
*this = *record;
else
return 0;
return this->time();
}
time_t Time::set(struct tm& time)
{
memcpy(this, &time, sizeof(*this));
return this->time();
}
double Time::difference(time_t other)
{
return std::difftime(*this, other);
}
time_t Time::operator = (struct tm& time)
{
return set(time);
}
time_t Time::operator = (time_t time)
{
return set(time);
}
bool Time::operator == (time_t other)
{
return (difference(other)==0);
}
bool Time::operator > (time_t other)
{
return (difference(other) > 0);
}
bool Time::operator < (time_t other)
{
return (difference(other) < 0);
}
const char * Time::printable()
{
return std::asctime(this);
}
/*
An example using the Time class.
*/
int main()
{
const char day[7][15] =
{
{"Sunday"},
{"Monday"},
{"Tuesday"},
{"Wednesday"},
{"Thursday"},
{"Friday"},
{"Saturday"},
};
Time now;
cout << day[now.weekday()] << ", " << now.month()
<< "/" << now.day() << "/" << now.year() << endl;
cout << now.hour() << ":" << now.minute()
<< ":" << now.second() << endl;
cin.get();
return 0;
}
/*
An example of timing a program using the Time class.
*/
int main()
{
int i = 0;
Time start;
while(i++ <= 1000000000)
continue;
Time stop;
Time performance = stop-start;
say("One billion loops took"
" %i minutes and %i seconds.",
performance.minute(), performance.second());
return 0;
}
Hammer
02-23-2003, 06:23 PM
Seb, you care to put any comments around that code or at least a brief description as to what it does and how?
Also, I tried compiling your directory walker, but couldn't. Now, this is obviously highly compiler specific code, so I have 2 questions for you: What compiler does the code compile with, and is that code directly from your editor (as I can't compile it, I can't verify the code myself).
Thanks, btw :)
Sebastiani
02-23-2003, 08:38 PM
This will compile on VC++, Bordland, and Dev-C++:
#include <dirent.h>
#include <iostream>
static char CURRENT_DIRECTORY[1024];
void
Search(const char * folder, const char * substring)
{
DIR * directory = opendir(folder);
if(directory == NULL) return;
chdir(folder);
_finddata_t * file = &directory->dd_dta;
long index = _findfirst("*", file);
do
{
if(strstr(file->name, substring))
{
if(file->attrib & _A_SUBDIR)
cout << " Folder:" << endl;
else
cout << " File:" << endl;
if(file->attrib & _A_ARCH)
cout << "(Archive)" << endl;
if(file->attrib & _A_SYSTEM)
cout << "(System)" << endl;
if(file->attrib & _A_HIDDEN)
cout << "(Hidden)" << endl;
if(file->attrib & _A_RDONLY)
cout << "(Read Only)" << endl;
getcwd(CURRENT_DIRECTORY, 1024);
cout << CURRENT_DIRECTORY << "\\" << file->name << endl;
}
if(file->attrib & _A_SUBDIR
&& strcmp(file->name, ".") != 0
&& strcmp(file->name, "..") != 0)
{
Search(file->name, substring);
chdir("..");
}
} while(_findnext(index, file) == 0);
_findclose(index);
closedir(directory);
return;
}
I will add comments to the Time class later tonight.
- cheers.
deathstryke
02-25-2003, 08:18 AM
@deathstryke: Are you meaning this entry? I'll write something easier to understand if so.
Yep. Most of my code knowledge is pretty simple, so examples with as little extraneous stuff as possible tend to help. Thanks Hammer for the help last time I asked about this stuff, even though my compiler didn't quite like it.
golfinguy4
02-27-2003, 08:11 PM
An Intro to Pointers
Pointers are a great struggling point among peopple trying to the C/C++. There is an aura surrounding them implying that they are only something that true Gods can understand (which is obviously not true). When one uses an int or char or whatever, the value stored at the address of it is the actual value of the variable. However, pointers are different. Instead of holding a value, pointers hold a memory address. This means that if you do not dereference it, you will get the address that it points to. However, using the dereference operator (the little star thing that you always see… it looks like this: *), one can access the value that is in the address that is being pointed to by the pointer (try saying that 3 times fast). This means that the type of the pointer must be the same as the type of data you plan to access (unless you are using void pointers, where you can cast (Don’t worry about this now)). To get the actual address of the pointer, one must use the & (address of) operator. Here is some sample code to demonstrate this: (note, this code uses C++ output mechanisms and can be easily converted to C)
#include <iostream>
using namespace std;
int main(void)
{
int *foo; //declares a pointer to an int
foo=new int; //means that foo points to an int on the heap or free store (same thing, 2 different names)
*foo=4; //the address that foo is pointing too will now hold a value of 4
// Now here is where it all comes together
cout<<”The address of the pointer is “<<&foo<<”.”<<endl
<<”The address the pointer is pointing to is “<<foo<<”.”<<endl
<<”The value that is held in the address that the pointer is pointing to is “<<*foo<<”.”<<endl;
cin.get();//pause the program
delete foo;
return 0;
}
Another big feature of pointers is that you can make them point to other variables. In doing this, you can indirectly access a different variable. This allows you to manipulate the variable through the pointer. Take this example:
#include <iostream>
using namespace std;
int main(void)
{ int* foo;//again, we have a pointer to an int
int number;//just a regular int
foo= &number;//foo now points to number's address
//now, any change to foo will also change number
number=5;
cout<<"The address that number is at is "<<&number<<endl;
cout<<"This address being pointed to by foo "<< foo<<endl;
cout<<"number= "<<number<<endl;
cout<<"(accessed through foo) number= "<< *foo<<endl<<endl;
number=2;
cout<<"number= "<<number<<endl;
cout<<"*foo= "<<*foo<<endl<<endl;
*foo=10;
cout<<"Number= "<<number<<endl;
cout<<"*foo= "<<*foo<<endl;
cin.get();//pause the program
return 0;
}
golfinguy4
08-08-2003, 12:04 AM
Hammer, just to give you a heads up...
I was checking out the FAQ and realized with the new site design, some of it has become "clipped." It happens on multiple pages.
Originally posted by golfinguy4
Hammer, just to give you a heads up...
I was checking out the FAQ and realized with the new site design, some of it has become "clipped." It happens on multiple pages.
Same with the tutorials, you have to load the printable version to be able to read them.
Hammer
08-08-2003, 05:30 AM
thanks for the info.
can you give me a link to a broken page, I checked a few and they looked OK to me.
golfinguy4
08-08-2003, 07:03 AM
Broken here: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1043368520&id=1031248513
Broken: http://faq.cprogramming.com/cgi-bin/smartfaq.cgi?answer=1043368520&id=1031248513
I didn't go through all of them. But those are a couple of examples. Also, a bunch of others don't look to great as the text goes (and almost touches the border). This constrasts the nice margin on the other side.
confuted
08-08-2003, 08:46 AM
I checked the first 20 FAQ entries (WinXP/Mozilla) and they looked fine.
The tutorials also look fine, except that the yellow code boxes are getting clipped.
I could read all the content of both correctly.
Hammer
08-08-2003, 09:15 AM
Yeah, I see now, they don't look too snappy in IE, but are OK in Mozilla.
Another reason IE is lame...
Hammer
08-09-2003, 08:20 PM
I've fixed the FAQ pages as far as I can tell. Let me know if there's any more problems with it.
SinAmerica
11-25-2003, 07:26 AM
If you want to add a SDL specific section i would love to help out with that.
Hammer
11-26-2003, 08:14 PM
Feel free to write whatever you like. As long as it's accurate, relevant and educational etc I'll consider putting it up. :)
Hunter2
12-18-2004, 11:52 AM
Maybe someone should summarize the "Reference-counted smart pointer" thread and post that as a "How Do I"? I'd do it, but the stuff about Boost went right over my head.
siavoshkc
08-30-2006, 08:29 AM
And I have an idea: Force new members to see FAQ before doing anything else. I mean they can't enter the board until thay visit FAQ page.
Salem
08-30-2006, 11:05 AM
> 12-18-2004, 05:52 PM
> Today, 02:29 PM
Here's another one, force them to read the forum rules about bumping threads.
vBulletin® v3.7.0, Copyright ©2000-2008, Jelsoft Enterprises Ltd.