This version isn't doesn't have any loop at all. Is that correct?
Also, how did you manage to trap Ctrl-X using <iostream>? It was my understanding that this isn't possible.
This version isn't doesn't have any loop at all. Is that correct?
Also, how did you manage to trap Ctrl-X using <iostream>? It was my understanding that this isn't possible.
Because of the way the standard buffered stream input works, there is no way to capture the control characters using the <iostream> functions. You will need to use OS-specific functions to get raw keyboard input. In the case of Windows, it will also depend on whether you are using Win32 API directly, or a framework such as .NET; similarly, in Linux, it would depend on whether you are using a library such as NCurses.
I'm not sure that the earlier parts of the program are working correctly, either. This is a transcript of a run I made after compiling the program under GCC 4.4.1:
Type in a file name (ex: inputFile.txt) and press Enter: input.txt
Storing Input File Name...
Opening File...
Reading file...
Finished copying file 1
programming is for progr
Closing input file...DONE!
Converting file list to lowercase letters: 1
toLower: p
toLower: r
toLower: o
toLower: g
toLower: r
toLower: a
toLower: m
toLower: m
toLower: i
toLower: n
toLower: g
toLower:
toLower: i
toLower: s
toLower:
toLower: f
toLower: o
toLower: r
toLower:
toLower: p
toLower: r
toLower: o
toLower: g
toLower: r
toLower: ■
toLower:
toLower:
toLower:
toLower: z
toLower: ◄
toLower: >
toLower: w
toLower: Ç
toLower: ☼
toLower: >
toLower: w
toLower: (
toLower: ⌠
toLower: "
....DONE!
1Sorting list...............DONE!
programming is for progr, 0
Creating Unique List.....DONE!
Opening Output File...DONE!
Writing to output file....
DONE!
Closing output file..........DONE!
As you can see, it fails to read the file correctly. I would address this problem first, or, if it is working for you but not me, determine why it is behaving differently under different compilers.
As an aside, please use int main()
instead of void main()
. While some compilers accept void
, it is not actually correct according to the C++ standard.
On a related topic, under the current standards (both C++98 and C++11), the older C-style library headers all start with 'c' and do not have the '.h' extension. For example, <string.h>
and <stdlib.h>
are now <cstring>
and <cstdlib>
. Just so you are aware.
First off, we don't do other people's homework for them. Second, we don't do other people's homework for them. And third, we don't do other people's homework for them. Sensing a pattern here yet?
No one here will simply hand you a solution on a silver platter. If you show us what you've done, what you've tried to do, and what problems you've had with it, then we'll be happy to help. If you have specific questions, we can answer them, or at least point you in the right direction. If you have a program with a bug you can't swat on your own, we'll be glad to assist, so long as you pay attention to the forum rules and post sensible questions in an intelligent manner that we have some reasonable hope of answering.
But just cutting and pasting an assignment into a message, without even prefacing it with something like, "I have this homework problem that I can't solve...", is likely to get you booted from the message boards here and elsewhere - if you're lucky. What happens to you if you are unlucky is... well... let's just say that this guy probably won't be trying that again, on that forum or this one.
We take this issue seriously here. Very seriously. Asking us to do homework for you is a grave breach of academic ethics on your part, and actually doing so would be an even bigger breach …
How are you compiling this - using g++ in the console directly, using a Makefile, or using an IDE such as XCode? Are you certain that the library itself (not just the header file) is being included in you libraries?
I just noticed two serious problems with the code I posted. Here's the corrected code (I hope):
//************************************************
void insertAfter(int val, Node* ptr)
{
if (head == NULL)
{
head = new Node(val, NULL);
return;
}
Node *current;
//used to hold a copy of the current list.
Node *previous;
//used to know the value of the current element that must
//be shifted down one.
current = previous = head;
while(current != NULL)
{
if (current == ptr)
{
ptr->setNext(new Node(val, ptr->getNext()));
return;
}
previous = current;
current = current->getNext();
}
// reached the end of the list
previous->setNext(new Node(val, NULL));
}
There are two things that occur to me about insertAfter()
; first, that in the current version you aren't testing for the end of the list; second, that you want to insert the new node after the node pointed to by ptr
, but right now, you have it replacing ptr
, instead.
//************************************************
void insertAfter(int val, Node* ptr)
{
Node *temp0;
//used to hold a copy of the current list.
Node *temp1;
//used to know the value of the current element that must
//be shifted down one.
temp0 = temp1 = head;
while(temp0 != NULL)
{
if(temp0 == ptr)
{
temp1 = new Node(val, ptr->getNext());
ptr->setNext(temp1);
return;
}
}
// reached the end of the list
temp->setNext(new Node(val, NULL));
}
I can't promise that this will work, but it should. Note the use of the member indirection operator ( ->
), which is basically a shorthand for dereferencing the pointer and getting the member from the dereferenced value.
You forgot to include the first argument of the report()
function ( numItems
).
What is happening, what problems are occurring? As it is now, the program won't actually do anything, as you never call report()
.
You do need to install the version of Code::Blocks with MinGW bundled, however. It sounds like the OP may have tried using the installer for the IDE alone.
I do have to agree with Adak about Pelles C - it is about as simple as compilers get.
I believe that the problem arises from using counter1 as both the loop index and the counter for the number of times the extra number appears. Try the following code instead:
void printInts ( int randomArray[], int size, int& extra )
{
int counter;
for ( counter = 0; counter < size-1; counter++ )
{
cout<<setw(30)<<" Random number "<<(counter + 1)<<" generated "<<randomArray[counter]<<endl;
}
cout << " \n ";
extra = randomArray[size - 1];
cout <<setw(40)<<" The extra random number is: "<< extra << "\n" <<endl;
int counter1 = 0;
for ( counter = 0; counter < size - 1; counter++ )
{
if ( randomArray[counter] == extra )
{
counter1++;
}
}
cout << setw(38) << " The extra number occured " << counter1 << " times " << endl;
}
Since you need both a largest value and a smallest value, you will want to declare two variables to hold the two results. Assign the value of n1
to both of them, then substitute ' largest
' for the n1
in your comparisons. This will get you the largest value, just as it did before. Now do the same with the ' smallest
' variable, just reversing the comparison (that is, use greater than rather than less than).
#include<iostream>
using namespace std;
int main()
{
int n1,n2,n3,n4,n5;
int largest, smallest;
cout << "input number1\n";
cin >> n1;
cout << "input number2\n";
cin >> n2;
cout << "input number3\n";
cin >> n3;
cout << "input number4\n";
cin >> n4;
cout << "input number5\n";
cin >> n5;
largest = smallest = n1;
if(largest < n2)
largest = n2;
if(largest < n3)
largest = n3;
if(largest < n4)
largest = n4;
if(largest < n5)
largest = n5;
// TODO: the same thing as above, except replacing
// 'largest' with 'smallest' and '<' with '>'
cout << "The largest number is" << largest <<endl;
cout << "The smallest number is" << smallest <<endl;
return 0;
}
If you have studied arrays, there is a good way to simplify the code using an array instead of having separate variables named n1
, n2
, n3
, etc. Experiment with it a little, and you should find something useful.
As a final note, I have to ask you to write out full words rather …
What seems to be the problem with it? It looks as if it should do what you want, but we need to know what problem you are having in order to help solve it.
Also, please put your code examples in CODE tags in the future. The forum software does not retain indentation by default, so without the code tags, you lose the code's formatting, making it difficult to read clearly.
The problem with the name length comes from using gets()
, which doesn't check the size of the array it reads into; in this case, if the name is more than 20 characters long, it will overflow the buffer and cause a crash. You should always use fgets()
instead, or better yet, use the C++ iostream functions such as cin.getline()
.
BTW, you should always declare main()
as returning an integer value explicitly. While some older compilers (such as the one you seem to be using) will accept an implicit value for functions, the C++ standard requires explicit return types, especially for main()
, which must - I repeat, must - return an int
, in order for it to be valid C++ code.
Speaking of older compilers, if you can, I recommend getting a newer compiler that follows the current language standard. I realize you might not have a choice in the matter, when it comes to school work, but you should at least be aware that the language officially defined in 1998 (and updated this year) is quite different in some respects than what was used before then. If you are allowed to, get one of the new free compilers/IDEs such as Code::Blocks or Visual C++ Express.
You need to add the header for vectors,
#include <vector>
Try the following version of the display function:
void dispData(const Person list[], int size)
{
system("cls");
if(size < 1)
{
cout << "Nothing to display" << endl;
}
else
{
cout << "*******************************************" << endl;
for (int i = 0; i < size; i++)
{
cout << setw(10) << right << "Name: " << setw(32) << left << list[i].name << endl
<< setw(10) << right << "Address: " << setw(64) << left << list[i].addr << endl
<< setw(10) << right << "Phone #: "<< setw(13) << left << list[i].phone
<< setw(16) << right << "Email: "<< setw(32) << left << list[i].email
<< endl;
cout << "********************************************" << endl;
}
cout << right << setw(3) << size;
cout << " Contacts"<< endl;
}
system("PAUSE");
system("cls");
}
I am sorry but I dont seem to understand your questions. I thought AddressBook was declared here AddressBook contactList[MAX_SIZE] if not then I am totally misunderstanding what declaration is.
Yes, that is a declaration of a specific variable of the type AddressBook
; but you would also need to define the struct type AddressBook
before declaring any objects of that type. A typical definition for a struct would be:
struct AddressBook
{
std::string contactName;
std::string address;
std::string phone;
std::string email;
};
Something like that would be needed before you could declare a variable of type AddressBook
. The structure definition describes what an AddressBook
object is composed of.
OK, then. Where is AddressBook
declared, if not here? Is it declared at all? What are the members of the structure?
I notice a few other things like this all through the code. For example, at one place you have it as "Address Book" (with the space), which won't compile even if everything else were correct.
Hmmn, the reason I ask - well, one reason anyway - is because I think you have the wrong value for yards per mile. According to all of the sources I've checked, it should be 1760, not 1728. However, the program as I wrote it comes up with 70.79 miles when using the 1728 value, and only 69.5 miles when using the 1760 value. I'm trying to see where I got it wrong.
When you say it "won't run", do you mean it doesn't compile? Or that it crashes? Or that it runs, but not correctly? Can you be more specific?
The first thing I notice is that the AddressBook
type or class isn't defined anywhere. Is Person
supposed to be AddressBook
?
Oops. I've updated my code changes since then. Sorry.
You need to have an index on the monthNames[] array, otherwise what it will return is the pointer (address) of the array rather than the value.
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
int main ()
{
double avgRain = 0;
double rainSum = 0;
int count = 0;
int monthlyTotals[12];
string monthNames[] = {"January","Febuary","March","April","May","June","July","August","September","October","November","December"};
cout << "Please enter the amount of rainfall for each month, and press enter after each: " << endl;
for (count = 0; count < 12; count++)
{
cout << setw(9) << left << monthNames[count] << " : ";
cin >> monthlyTotals[count];
}
for (count = 0; count < 12; count++)
rainSum += monthlyTotals[count];
avgRain = rainSum / 12;
cout << "Output : " << endl;
for (count = 0; count < 12; count++)
{
cout << setw(9) << left << monthNames[count]
<< setw(3) << right << monthlyTotals[count] << endl;
}
cout << rainSum << " is the total rainfall for the year\n" << avgRain << " is the average for the year.\n";
return 0;
}
Note the use of the setw()
manipulator, which gives better control over the spacing than the tab character does. You will need to #include <iomanip>
in order to use the manipulators, however. Note also the change in the index conditionals, such that the count
variable goes from 0 to 11, rather than 0 to 12. The way it was originally, it was causing a segfault when it reached 12 and overran the arrays.
Usually, in the header file you would have a declaration of the function as a friend
of the class in the class itself, then outside of the class, you would have the function prototype itself.
#include <string>
#ifndef CREATURE_H
#define CREATURE_H 1
class Creature
{
private:
int statArr[6];
std::string name;
public:
Creature();
void rollStats();
void setStats();
void setName();
void viewName();
void viewStats();
friend std::ostream& operator<<(std::ostream& os, Creature& cr);
};
std::ostream& operator<<(std::ostream& os, Creature& cr);
#endif
Then in the code file you would have the actual function:
std::ostream& operator<<(std::ostream& os, Creature& cr)
{
os << cr.name; // just an example
// any other output you see fit to have here
return os;
}
You'll want to add a check for file.good()
after the first getline()
in each iteration, or better still, set up a loop and check each one:
void FileInput()
{
ifstream file ("test1.csv");
while ( file.good() )
{
string value[7];
for (int i = 0; i < 6; i++)
{
getline ( file,value[i], ',');
if (file.eof() || file fail())
break;
}
getline ( file,value[6]);
if (file.good())
{
FileInfo* fi = new FileInfo();
fi->submissiontime = atoi(value1.c_str());
fi->length= atof(value3.c_str());
fi->finishtime= atoi(value5.c_str());
fi->remainingtime= atoi(value7.c_str());
futurelist.push_back(fi);
}
}
file.close();
}
As for troubling us, don't worry too much about it, you're new here, and still learning. No one knows what they are doing the first time they post.
First off, please use CODE tags around your code samples in the future; the forum software does not retain the code indentation, and without the formatting the code is almost unreadable.
Second, the data you posted isn't in Comma-Separated-Values (CSV) format, but in a space-separated format. This doesn't seem to be a problem with the code, but it is a bit confusing to those of us reading this and expecting commas. Your code is written to work with a CSV file, so presumably, the actual file is in fact a CSV file.
Third, why did you have a series of separately declared strings (value1, value2, etc.) rather than an array, a structure, or a collection object? Again, it isn't a problem with the program per se, but it seems like a poor design, especially when you later use a list object and thus presumably know how to use collections.
Fourth, you are using a global variable for said list, which is generally considered a poor approach. While this appears to be something of a throw-away program - frankly, I would have used Perl or something like that for a small thing like this - it's still good practice to avoid globals.
Fifth, the list is set to contain objects of type FileInfo, but that class or structure isn't defined anywhere in the given code.
Sixth, you never delete the allocated FileInfo objects. Again, it shouldn't affect the program too much, but it's sloppy coding.
Finally, as for the problem you …
Nevermind, I see Narue found the problem, which I had missed.
A Graphical User Interface program, i.e., a typical Windows program, as opposed to one in a text-only console window. GUI programs are more flexible, but a lot harder to write, which is why most introductory courses stick to console applications.
Could you go into more detail about what you're looking to do? Operator overloading should work similarly to any other function or method, regardless of whether it is divided into multiple files or not. Or were you referring to data files?
Curiously, when using Code::Blocks 10.5 (MinGW GCC 4.4.1), I get the following result from the same dataset:
John Doe
T00001264
Freshman
Second
0
Jane Doe
T00012345
Senior
First
3.62
I'm not sure what the cause of the discrepancy in the results is.
Crystalll: As an aside, in the future, please put CODE tags around your code samples. The forum software does not retain formatting by default, so your code loses it's indentation unless it is in code tags.
Assuming we're talking about overloading the input and output functions, the general approach is to make a friend
function which takes a stream of the appropriate type, and an object of the class to be printed. You would need to add the following declaration to your class:
friend std::ostream& operator<<(std::ostream& os, Rational& r);
You would then implement the function outside of the class, but because it is a friend
, it would have access to the internals of the class. The output function is actually quite close to what you already have for you printRational()
method:
std::ostream& operator<<(std::ostream& os, Rational& r)
{
os << r.numerator << "/" << r.denominator;
return os;
}
Note that I explicitly referred to the std
namespace when declaring the ostream&
objects; this is because (as explained here in mind-numbing detail) it defaults to assuming that the class ostream&
is in the global namespace otherwise, wheras you actually want the class that is in the std
namespace. This is why I had advised against the using
directive earlier.
Overloading the istream operator>> is similar, but a bit more complicated, as you will want to read in the '/' but ignore it; using the ignore() method is probably the best way to do this.
Also, you need to be careful not to allow a zero denominator. Usually, you would throw an exception in this case, but I'm guessing your course hasn't covered exceptions yet. I'm not sure what to recommend, other …
As an aside, why did you change your main()
from int main()
to void main()
? The correct form is int main()
; strictly speaking, void main()
shouldn't compile at all.
Also, I would separate the class definition and implementation into separate files from the main()
function, just to keep the whole thing cleaner. Note that you generally want to avoid using the using namespace std;
directive in header and class implementation files, especially if you are going to implement an overloaded operator<<
or operator>>
for I/O.
I just noticed something in the for() conditional:
for( i=sr-1, j=sc+1; i>=h,j<=k; i--, j++ )
First off, where are h
and k
coming from? They aren't declared in the function and they aren't arguments, so I assume that they are globals. What do they represent, the sizes of the chessboard? If so, then it will always check to the edge of the board, even if the intended destination is only partway across the board.
Second (and I really should have noticed this before), using the comma operator in the conditional (as opposed to the initializer or the increment) essentially ignores the second part of the conditional. What you want is
for( i=sr-1, j=sc+1; i>=h && j<=k; i--, j++ )
While this probably doesn't impact the problem you are posting about, it could be the source of other problems.
The initializer issue should not cause a variable not to be declared; you'd still have
struct Student_info {
std::string name;
double overall;
};
It simply wouldn't have an initial value, so you'd have to calculate the values before storing them in overall
.
I think you may be taking the part about the structure calculating the grade too literally; I suspect that what is intended is for you to change the input functions so that, rather than storing the grades directly, they read in the grades, compute the totals, then store it. So all you really need to do is simplify the structure as I have done above, and modify read()
.
Does it work with two strings of greater than zero length? If it does, you may need to test for the string length for both strings.
One thing strikes me most of all, that you did not, in fact, close and re-open the file as the instructions said would be necessary. This is probably the main reason it isn't working, and the data you are getting is probably garbage that was already in the allocated memory.
BTW, what is the correct figure for the number of miles passed? Just curious.
I think I've got it figured out. The problem is in the line getline(input, team, '\t');
. Because the text file does not, in actual fact, have any tabs, it ends up reading the whole file into that one string.
Personally, I would have done it somewhat differently, using an array of the following structure:
struct TeamRecord
{
string name;
int yards;
int passyards;
int points;
}
But that's just me. Note that I used integers for the various stats; this is because all of the stats you are interested in are, in fact, whole number values. More about this shortly.
One of the problems you have in the code is that you never increment i
in calculatedata(
), which means that you keep reading to the same location over ansd over again... or you would be, if it didn't stop mysteriously on the first line. I'm still trying to figure that out, myself.
As it is, all that you are checking is whether the region between the source and the destination is clear; you never check to see if the destination is actually on that diagonal.
bool validBishop(char board[][8],int inputs[])
{
int sr=inputs[0] , sc=inputs[1] , dr=inputs[2] , dc=inputs[3];
int i, j;
bool clear = true;
if(sr>dr && sc<dc)
{
for( i=sr-1, j=sc+1; i>=h,j<=k; i--, j++ )
{
if(board[i][j] != ' ')
{
clear = false;
break;
}
}
}
return (clear && (i == dr) && (j == dc));
}
Good point, I was overthinking things I suppose. My mistake.
One thing I noticed (aside from your indentation, which needs improving) is that the project said to set the file to append mode. Thus, you should change the open() call to:
file.open("output.txt", ios::out | ios:app);
This ensures that the data is added to the end of the file, rather than overwriting the data already there.
Odd, I was having what is in some ways the opposite problem - when I compile and run the program, it accepts the first set of questions and answers, then prints out the series of inquiries for the remaining questions all at once, then ending.
Enter the limit of questions
4
Enter the question
why
enter the four options
why not
because
who knows
fish
Enter the answer for the respective questions
fish
Enter the question
enter the four options
Enter the answer for the respective questions
Enter the question
enter the four options
Enter the answer for the respective questions
Enter the question
enter the four options
Enter the answer for the respective questions
While I was working on that problem, I noticed one thing: as it is now, you are overwriting each question with the next one. You want to have q
be a pointer to qa, and assign it a dynamically allocated array. You also need to change how you write to the file, as the way you're doing it now won't work - you need to 'serialize' the separate members of the object one at a time to get consistent results.
This code seems to work now:
#include <iostream>
#include <cstdio>
#include <fstream>
#include <string>
using namespace std;
class qa
{
char question[35];
char option[4][20];
int ans; //correct option no (eg 0 1 2 3)
public:
void getques()
{
cin.getline(question, 35);
}
void getopts()
{
for (int i = 0; i < 4; …
Urk, I had missed the use of gets()
in the original, or I would have mentioned it... using gets()
, under any circumstances, is a serious problem, as it doesn't check to make sure that the input will fit into the buffer it reads into. Using gets() is just asking for buffer overruns; in C++, you should use cin.getline()
instead.
void getopts()
{
for (int i = 0; i < 4; i++)
{
cin.getline(option[i], 20);
}
}
BTW, your indentation style is, to be blunt, atrocious. Please be more careful about indentation, or else use an auto-formatter (VC++ 6.0 includes one, IIRC).
What you want is a sorting algorithm, from the way you describe it. You can find descriptions of various sorting methods on Wikipedia; I personally suggest the Gnome Sort, as it is very simple and easy to debug, though not particularly efficient.
Did you actually mean to mark this 'solved'? You seem to mark it almost as soon as it was posted.
Also, as has been explained before, void main()
is incorrect, despite the fact that the compiler says it is acceptable. Please use int main()
in C++ programs, always.
You need to move the final word count out of the while() loop. You also need to check for in.fail() in the loop itself, in case there's a problem with the input that did not appear when it was opened.
EDIT: I think I know where the problem lies: you need to use in.get() rather than the << operator to read in the characters. Here's a modified version of your code that ought to work correctly:
#include <fstream>
#include <iostream>
#include <string>
#include <cstdlib>
#include <cctype>
using namespace std;
int main()
{
int words = 0, count = 0, letters = 0;
int ch = 0;
int Option1;
string FILE;
cout <<"Hello, This program will count the number of words in a file of your choice!"<<endl;
cout <<"If you are ready to begin enter 1 and press enter, press 2 and enter to exit."<<endl;
cin >> Option1;
if(Option1==2)
{
cout <<"Have a nice day"<<endl;
cout <<endl;
system("pause");
return 0;
}
if(Option1==1)
{
cout <<"Alrighty lets begin, Please enter the name of the file you wish to open"<<endl;
cout <<"Also include the file format! for example(.txt, .doc, .rtf ect...)"<<endl;
cin >> FILE;
ifstream in;
in.open(FILE.c_str());
if(in.fail())
{
cout << "input file failed to open." << endl;
exit(1);
}
while(!in.eof() && !in.fail())
{
ch = in.get();
// cout.put(ch);
letters++;
if((ch=='.') || isspace(ch))
{
words++;
}
}
cout << endl;
cout << "There are " << letters << " characters and" << endl;
cout << "There are " << words << " …
Don't mention it. BTW, I think I found another thing you'll want to fix: the radioactive() function doesn't do what I gather you want it to. Try this:
bool radioactive()
{
return (rand() % 100) < 2;
}
The modulo operator ( %
) returns the remainder of the first number divided by the second number, so if you have 123 % 100, you get 23 back. The new version of the function should return true 2 percent of the time, now (on 0 or 1).
Actually, as you have it now, it isn't going to work, because your createNewBunny()
function is broken. Right now, you are assigning each of the different attributes - gender, color, age, name and radioactive - to a different Bunny object. You never create a single actual Bunny.
I would start to fix this by separating the declarations of the Bunny objects from the class, by deleting object g, c, a, n, and r objects.
I would then separate the creation of the Bunny objects from the input and output by creating a Bunny() constructor method for the class.
And re-write the createNewBunny()
function so that it only gathers the information from the user.
Finally, change main() to reflect this new state of affairs Putting this all together you would have something like this:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <cstdlib>
#include <cctype>
#include <ctime>
using namespace std;
#define DEBUG 0
#define WINDOWS 0
void clearScreen()
{
#if (DEBUG != 1)
#if (WINDOWS == 1)
system("cls"); // we're running under Windows
#else
system("clear"); // we're in a civilized operating system
#endif
#endif
}
ofstream fp("text.txt");
class Bunny
{
private:
string gender;
string color;
int age;
string name;
bool radioactive;
public:
Bunny(string g, string c, int a, string n, bool r);
};
Bunny::Bunny(string g, string c, int a, string n, bool r): name(n), radioactive(r)
{
if (g != "male" && g != "female")
throw ("Invalid Gender");
else
gender = g;
if (c != "white" …