How to search and use a file in ssh/server - c++

My c++ program is being run on xCode. One part of my program is searching for a file that's on my computer and using it to store the values into an array. Everything is working just fine on xCode, but when I moved my files .cpp .h .txt into a server or ssh it doesn't seem to be working.
This is a snippet of my code:
case 'W':
if(heap.capacity == 0)
cout<< "Sorry!!! It cannot be done. Please initialize the heap first.";
else{
file.open("/Users/mbojo/Downloads/HEAPinput2.txt");
int line;
int count = 0;
while(file>>line)
count++;
file.close();
heap.capacity = count;
cout<< "COMMAND: " << choice << "\n" << "The capacity is "<<
heap.capacity << "\nSize is " << heap.size<<endl;
}
break;
Is there anything I need to change in ssh/server that can read the file.

Related

My files are never opening?

Whenever I try to make a program based on files, my program is never able to open the file itself.
It always ends up executing the part of the program in the "else" part. Is it because my file might not be in the same directory? If so, how do I find the location of my file? Here's the code. I just wanted to check if its working fine or not by inputting and outputting the strings using the concept of files.
int main()
{
char str1[20], str2[20];
FILE *pFile;
pFile = fopen("Rocket.txt", "r+");
if (pFile != NULL) {
while (feof(pFile)) {
cout << "Enter String 1: " << endl;
fgets(str1, 20, pFile);
cout << "Enter String 2: " << endl;
fgets(str2, 20, pFile);
cout << "The Strings input are: " << endl;
fputs(str1, pFile);
fputs(str2, pFile);
}
}
else {
cout << "File not opened." << endl;
}
1) "How do I find the location of my file?"
right-click on your file
properties->Details->Folder path or
properties->General->Location
For example if it was C:\Users\user\Desktop then the location you write is c:\\Users\\user\\Desktop\\Rocket.txt
2) In your code, I found two bugs
Notice that in the "while condition" you should write (feof(pFile)==0) or (!feof(pFile)) because it should continue reading from file until it reaches the end of file and feof(pFile) == 1.
"puts" writes at the end of the file. So when the file marker is not at the end of the file, it doesn't write on it, unless your initial file has just 37 characters. So it's not a good idea to use "puts" in this program. Instead , you can use cout to check out values of str1 and str2.

Function not reading and printing file content in c++

Hi guys im working on a school project which is an rpg game. I have created a load_game function which is supposed to go through a specific file, check if the file has the id the user enters and load that specific characters stats into global variables.
The problem is that I made a function to print out the content of the file so the users can see their options but it doesnt print anything at all, I made a new_player function which fills the same file with new players and that works correctly. When i change a file to another one and write into that file manually it works. Here is the code:
void load_game()
{
bool loading = true;
do{
ifstream in_stream("Players.txt");
ofstream out_stream("Players.txt");
cout << " The last son of Allheaven " << endl;
cout << "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+" << endl;
char ch;
in_stream.clear();
in_stream.seekg(0, in_stream.beg);
while (in_stream.get(ch))
{
cout << ch;
}
cout << " Enter -1 to return to main menu " << endl;
cout << "+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+" << endl;
cout << endl << "Enter a number to access one of the above options: ";
in_stream.clear();
in_stream.seekg(0, in_stream.beg);
int choice;
cin >> choice;
while (in_stream >> ID >> Name >> Class >> HP >> Mana >> ATK >> ability_dmg >> Defense >> magic_resist >> player_exp >> player_level)
{
if (choice == ID)
{
/*game_start();*/
loading = false;
break;
}
else if (choice == -1)
{
system("cls");
main_menu();
}
else if (in_stream.eof())
{
in_stream.clear();
in_stream.seekg(0, in_stream.beg);
cout << endl << "Error! Invalid ID !" << endl;
}
}
in_stream.close();
out_stream.close();
} while (loading);
}
A major problem is that you open the same file twice. Once for input, and once for output which will truncate the file if it exists. So when you create out_stream you will effectively remove all the data in the file.
If you want to read from and write to the same file either use std::iofstream to open it in read/write mode. With text files it's hard to edit data in the file though, so I rather recommend you open a temporary file for the output, and when done you rename the temporary file as the actual file.
Or in your case, why have the output file at all? You don't actually use it anywhere? All it does is truncating the file you want to read.

strcmp() function does not compare properly against user input and struct file data

I'm trying to solve this issue where when i try and search for a certain module name in my .dat file, it doesn't show the info of some module like module name, module code.
Example: if I search CSCI124, it shows all of the needed info i need in the output.
However if i try searching for CSCI114 or MATH121, it doesn't show any info except for "Subject Code not found.."
I have tried playing around with not putting in the while loop however it doesn't work as well.
It would be awesome if you guys could help me out, just started learning about c++
Subject subjectDB;
char subCode[MAX];
int printOnce = 0;
int position = 0;
cout << "Enter Subject Code: ";
cin >> subCode;
// Open binary file
ifstream fin("Subject.dat", ios::out | ios::binary);
if (!fin)
{
cout << "\nError opening database..\n"
<< "\tQuitting System..";
exit(-1);
}
cin.clear();
cin.ignore(100, '\n');
while(fin.read(reinterpret_cast<char*>(&subjectDB), sizeof(Subject)))
{
if (!(strcmp(subCode, subjectDB.subjectCode) == 0))
{
// Print this section once
if (printOnce == 0)
{
cout << "Subject Code not found..\n";
printOnce++;
}
}
else
{
// Print this section once
if (printOnce == 0)
{
cout << "\nSubject Code: "
<< subjectDB.subjectCode
<< "\nSubject Name: "
<< subjectDB.subjectName
<< "\n"
<< endl;
cout << "Task\t"
<< "Title\t\t"
<< "Weight\t"
<< "Upon\t"
<< "Mark\t"
<< "Obtained\n";
// PrintOnce++ : 1 != 0
// So it only prints once
printOnce++;
}
cout << position + 1
<< "\t"
<< subjectDB.assessment[position].title
<< "\t"
<< subjectDB.assessment[position].weight
<< "\t"
<< subjectDB.assessment[position].upon
<< "\t"
<< subjectDB.assessment[position].taskMark
<< "\t"
<< "testing\n";
position++;
}
}
Writing a struct to a file or reading a struct from a file is totally non-portable. Compile the same code on two different compilers, or on the same compiler with different settings, and what you wrote and what you read might be very different. That's not necessarily your problem, but it will be your problem one day.
Your display code logic is flawed.
Explanation:
If the subject code is in the first record you read, you'll get the correct answer. However as soon as your fist record does not match, the "Not found" message is displayed, printOnce is incremented. If the matching subject coe is found later in the file printOnce is no longer 0 and it' will not be displayed.
Solution:
Organise your loop in the opposite way:
while (...) {
if (strcmp(..)==0) {
// your code to display the found item here
printOnce++;
break; // ?? optional: you could stop the loop at first found occurence unless you suppose there could be duplicates
}
}
and once the loop is finished, check OUTSIDE OF THE LOOP if you've found something:
if (printOnce==0) { // nothing was found in the loop
// display that nothing was found !
}
Remark:
Reading directly from file as you do has limitations. It can only work with plain old data (POD), not with more advanced types using string members or containters. For learning it's a good start but I'd suggest to foresee a Subject member function that loads the data from a stream. This proves to be more flexible when your data structure evolves: the member function could ealsily read each member data and sub-objects using the most apporpriate way.
Thanks for your help! I managed to get the function to compare properly against user input and struct file by creating a function that checks the .dat file if the subject is existing or not.
int row = checkNumberOfData(fileName);
if (row > 0)
exist = doesSubjectExist(file, fileName, code); // checks input
if (!exist)
{
file.open(fileName, ios::out | ios::app | ios::binary);
if (!file)
{
cout << "Error opening database..\n"
<< "\tQuitting System ..\n";
exit(-1);
}
strcpy(subjectDB.code, code);
cout << "Subject Name: ";
cin.getline(subjectDB.name, MAX);
cout << "No of assessment tasks: ";
cin >> subjectDB.num;
cout << endl;
.... etc
}

else if looping quandry

I am in the second phase of a project where I need to extend my program into a menu driven application to query the database I have on a .txt file. So, my trouble is that I cannot get my loop to be perpetual. It always terminates when it initializes from one option to the next. Here is the snippet of my code that is my int main:
int main ()
{
char Q,q;
char S,s;
char task;
string pathname;
string z;
int count=0;
cout << "Welcome to Jason Rodriguez's Library Database." << endl;
cout << "Please enter the name of the backup file: ";
cin >> pathname;
ifstream inFile(pathname.c_str());
while(!inFile.eof())
{
getline(inFile,z);
count++;
}
while (task != 'Q' || task != 'q') {
cout << count << " records loaded successfully." << endl;
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> task;
if ((task == 'Q')||(task =='q'))
{
cout << "Program will now terminate";
break;
}
else if ((task == 'S')||(task =='s'))
{
showAll (loadData (pathname));
cout << endl;
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> task;
}
}
}
I need to add two more options into the loop on top of these two but I figured I should get the first two working correctly first. The other two should be plug & chug after that. Basically what I was trying to do is say if the user enters Q or q, terminate the program. Else, if user hits S or s, activate showall function and after ward, go back to the original query. It isn't working though. Assistance is welcome and appreciated.
Menus almost always require loops - especially ones that require the user to enter the correct choice input. The most applicable one in a case like this is the while loop - but essentially, any other loop variant can be used.
UPDATE:
int main ()
{
char task;//this is the only char needed. Your other chars were redundant
string pathname;
string temp;//I changed z to temp to better reflect its purpose
int count=0;
cout << "Welcome to Jason Rodriguez's Library Database." << endl;
cout << "Please enter the name of the backup file: ";
cin >> pathname;
ifstream inFile(pathname.c_str());//this is potentially a problem in that you aren't verifying that the pathname is a valid one
//you did not check to see that your file was open, otherwise there is no way to tell that you successfully opened the file
if (inFile.is_open()) {
//while(!inFile.eof()) is a character by character read and comparison
//made your life easier by shortening it down to this - which ensures
//that a line is read. (Much faster and more readable)
while(getline(inFile,temp))
{
count++;
}
inFile.close();//always close a file after you've used it
//At this point the entire file has been read. So, this is where this message SHOULD be
cout << count << " records loaded successfully." << endl;
}
else {
//if there was an error opening the file (i.e. wrong path, or it simply does not exist), this will be displayed
cout << "There was a problem opening your file" << endl;
exit(0);//and the program will terminate
}
while (task != 'Q' || task != 'q') {
cout << "Enter Q to (Q)uit, Search (A)uthor, Search (T)itle, (S)how All: ";
cin >> task;
if ((task == 'Q')||(task =='q'))
{
cout << "Program will now terminate";
break;
}
else if ((task == 'S')||(task =='s'))
{
string author;
//showAll (loadData (pathname));
cout << endl;
cout << "Search an Author" << endl;
cin >> author;//get the author name to search from the user
//write code to search an author here
}
}
}
There are a number of issues with the code that you posted which I will forgo for the sake of brevity. Hence, note the following:
Your code was printing the same message per option (except for quit). Of course it would appear that it didn't work. Each option is a different task. Print what each task does (similar to what I did).
You wish to search the file for an author, but you have not stored it. Look into a way of storing it that appeases your instructor.
It would be ideal for you to use switch in this case, considering the increasing complexity of your code.
Try breaking down each task into functions, and call them to make your main function readable. In fact, it is a good programming practice for your main function to be as small as possible.
And, as juanchopanza quite rightly pointed out: you have some fundamental issues with C++. Try doing some more exercises and do more examples from a good C++ book.

C++ getline or cin not accepting a string with spaces, I've searched Google and I'm still stumped!

First of all, thanks to everyone who helps me, it is much appreciated!
I am trying to store a string with spaces and special characters intact into MessageToAdd.
I am using getline (cin,MessageToAdd); and I have also tried cin >> MessageToAdd;.
I am so stumped! When I enter the sample input
Test
Everything works as intended. However if I were to use
Test Test Test
The whole console would just blink fast until I pressed CtrlC.
My style of putting variables at the top I've been told is obsolete. Please forgive me as I am still teaching myself and it's simply force of habit. I will be changing my style shortly after I get this solved :)
void AddMessage() {
ifstream myReadFile;
string str;
string MessageToAdd;
string myMessages[10];
int i; // of course my famous i
static string rowHtmlCloseTags;
static string rowHtmlOpenTags;
string replacement;
myReadFile.open("C:\\Users\\Andrews\\Documents\\Visual Studio 2010\\Projects\\computerclass\\Debug\\outages.htm",ios::in);
i = 0; //the start of my array
rowHtmlCloseTags = "</b></td>"; // value that I want to replace with nothing
rowHtmlOpenTags = "<td><b>";
if(!myReadFile) // is there any error?
{
cout << "Error opening the file! Aborting…\n";
exit(1);
}
if (myReadFile.is_open())
{
cout << endl;
while (!myReadFile.eof())
{
getline(myReadFile, str);
if (str == "<tr>")
{
getline(myReadFile, str); //get the next line cause thats where the <td><b>Outage Message</b></td> is.
size_t foundIndex = str.find(rowHtmlCloseTags); //does the sought string exist in this this line?
if (foundIndex != str.npos) //if not no position
str.replace(foundIndex, rowHtmlCloseTags.size(), replacement); //replace the string
else
std::cout << "Oops.. didn't find " << rowHtmlCloseTags << std::endl; //else throw a bitch
foundIndex = str.find(rowHtmlOpenTags); //does the sought string exist in this this line?
if (foundIndex != str.npos) //if not no position
str.replace(foundIndex, rowHtmlOpenTags.size(), replacement); //replace the string
else
std::cout << "Oops.. didn't find " << rowHtmlOpenTags << std::endl; //else throw a bitch
myMessages[i]=str;
i++;
}
}
}
system("cls");
i=0;
while (i < 10)
{
cout << i << ") " << myMessages[i] << endl;
i++;
if (myMessages[i]=="")
{
break;
}
}
myReadFile.close();
cout << endl;
cout << endl;
cout << "Enter the message you would like to see on the reader board.\n";
cout << "Or enter 911 to go back to the main menu: ";
cin.ignore(1080);
getline (cin,MessageToAdd);
if (str == "911") //go back to the main menu
{
system("cls");
mainMenu();
}
else //insert the message into a blank spot in the array
{
i=0;
while (i < 10)
{
if (myMessages[i].empty())
{
myMessages[i]=MessageToAdd;
break;
}
else
{
i++;
}
}
}
//now rebuild the htm file with the new array
CreateHtmlFile(myMessages);
}
I'll tell you one thing that's immediately wrong with your code, not your specific problem but a hairy one nonetheless.
I'm presuming that your mainMenu() function is calling this one. In that case, you appear to be under the misapprehension that:
if (str == "911") //go back to the main menu
{
system("cls");
mainMenu();
}
will return to your menu. It will not do that. What it will do is to call your main menu code afresh and eventually you will run out of stack space.
I suspect that what you should be doing is having a loop in mainMenu() and that code above should just use return; rather than calling mainMenu() recursively.
That and the fact that I think you should be comparing MessageToAdd against "911" rather than str.
Another thing I would do would be to put some temporary debug code in:
cout << "DEBUG A\n";
i=0;
while (i < 10)
{
cout << "DEBUG B " << i << "\n";
if (myMessages[i].empty())
{
cout << "DEBUG C\n";
myMessages[i]=MessageToAdd;
break;
}
else
{
i++;
cout << "DEBUG D " << i << "\n";
}
cout << "DEBUG E\n";
}
cout << "DEBUG F\n";
and see what gets printed. Of course, you could trace the execution in a debugger but that would require you to do the work yourself. If you just post the output (first 100 lines if it's huge), then we can probably tell you what's wrong easily.
Actually, I think your problem is the cin.ignore. When I run your code, nothing works, neither Test nor Test Test Test. That's because it's ignoring the first 1080 characters I'm trying to input. Proof can be seen when you change those statements to:
cin.ignore(1);
getline (cin,MessageToAdd);
cout << MessageToAdd << "\n";
and you get est output when you enter test.
Take out the ignore line and try again. I'm not certain of this since you seem to indicate that Test works but I can't see this as being correct.
So here's what you need to do (at a bare minimum):
get rid of the cin.ignore altogether.
use return rather than mainMenu().
use if (MessageToAdd == "911") instead of if (str == "911").
let us know how it goes then.