File Handling and if else - c++

I am trying to make a program for my University project and I needed some help.
I am trying to make a program which creates a file using ofstream and stores 1 or 0 in it (I've already found a way to store 0 or 1 in the file using random) and tells if the file contains 0 or 1 using if-else statements.
I'm having issue in reading the file, I can't find a way to make my program read that created file and tell whether it had 1 or 0 in it.
Here's my code:
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
using namespace std;
int main () {
int randu;
srand((int) time(0));
ofstream room;
room.open("room0");
room << rand() % 2;
room.close();
if (room.open("room0") == 1 ) {
cout << "the room is occupied";
}
else {
cout << "the room is free";
}
room.close();
return 0;
}

I'm having issue in reading the file ?
You are not reading anything in the code you shown.
Once the file is open and you want to check whether it's 0 or 1, for that first you need to read from file and if you want to read something, then room should be object of ifstream class, not ofstream class.
You can use getline() or get() or read() for reading purpose.
For example: char ch = room.get();
Whether the file is open or not you can check using fail():
if(room.fail()) {
cout << "the room is occupied";
}
else {
cout << "the room is free";
}

Related

finding a word from a file and substitution into other file

I have two text files like these:
11.txt:
1 5.66
2 4.95
3 2.55
4 0.99
5 2.87
NB.txt:
1 2 3 4 5
4 5 3 2 1
3 4 5 1 2
I have written the below code to fine, for example, "1" from File 1, and search it in File 2, then substitute "1" with "5.66". and repeat it for other numbers, i.e. 2,3,4,5. but I don't know why it doesn't work. additionally, it doesn't read the first line of 11.txt.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main ()
{
string line;
double AtomId, Atom_radius,search ;
ifstream AtomId_file ("11.txt");
string namefile;
if (AtomId_file.is_open()){
for (int linenox = 0; getline (AtomId_file,line) && linenox < 6; linenox++){
if (linenox == 0) AtomId_file>>AtomId>>Atom_radius;
}
cout<<"AtomId: "<<AtomId<<" Atom_radius: "<<Atom_radius<<endl;
cout<<namefile<<"\n";
}
ifstream NB("NB.txt");
size_t pos;
if (NB.is_open())
{
search = AtomId;
getline(NB,line);
pos=line.find(search);
if(pos!=string::npos)
{
search = Atom_radius;
cout <<"Found!";
}
}
ofstream myfile;
myfile.open ("12.txt");
myfile << search << "\n";
}
the output in 12.txt is:
2
instead of :
5.66 4.95 2.55 0.99 2.87
0.99 2.87 2.55 4.95 5.66
2.55 0.99 2.87 5.66 4.95
I understand that your are new to C++.
I analyzed your code and put in tons of comments, where the errors are. You need to change your design. Before starting to type in code, you must first write down, what should be done. Then, and this is most important, you think (without taking any language into consideration) how you can solve the problem. This is most important. Also for you later programming career. The design is most important. So think 3 hours, how it could be done. Search possible design solutions in the internet. Write it on a piece of paper or somewhere.
Then, after hours of thinking, select an apropriate language and check, how it could be implemented.
I show a standard C++ solution below. You will not understand it immediately. So please try to understand the design first. Then lookup all used C++-statements in the internet and try to understand.
Read some good C++ books, before starting to code.
Please see first your commented code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std; // You should not use this line at all. Use qualified names.
int main()
{
string line;
double AtomId, Atom_radius, search; // These variables are not initalized
ifstream AtomId_file("r:\\11.txt");
string namefile;
if (AtomId_file.is_open()) { // You should not use is_open but simply if (AtomId_file)
// Here you have a loop running from 0,1,2,3,4,5. That are 6 loops. But you have only 5 lines in your sourcefile
// The you read one line, each time the loops runs. So in the beginning, this will read the first line
for (int linenox = 0; getline(AtomId_file, line) && linenox < 6; linenox++) {
// And only for the first loop event, when linenox==0, you read then next line "2 4.95"
// So you read already lines. But not more.
// ypu need to read line by line (only one per loop) and then store the result in an appropriate STL Container
if (linenox == 0) AtomId_file >> AtomId >> Atom_radius;
}
// Since you assigned the data only once, the values will be 2, 4.95
// They will never change
cout << "AtomId: " << AtomId << " Atom_radius: " << Atom_radius << endl;
// The variable namefile has never been initailized and is always emtpy, So ""
cout << namefile << "\n";
}
ifstream NB("r:\\NB.txt");
size_t pos; // Not initialized
if (NB.is_open()) // Not recommended. Use "if (NB) instead". In general, use more meaningful variable names
{
search = AtomId; // search is now 2 and never somthing else
getline(NB, line); // Read exactly one (and only this one time) a line containing 1, 5.66
pos = line.find(search); // So, 2 will never be found
if (pos != string::npos) // Always false, can never be true
{
search = Atom_radius; // Will never be executed
cout << "Found!"; // Will never be executed
}
}
ofstream myfile; // You can write directly ofstream myfile("12.txt");
myfile.open("12.txt");
myfile << search << "\n"; // And the output will always be 2.
}
And here is a correct and working example:
#include <iostream>
#include <fstream>
#include <string>
#include <sstream>
#include <unordered_map>
#include <vector>
#include <iterator>
int main() {
// Open the file 11.txt and check, if it could be opened
if (std::ifstream file11("11.txt"); file11) {
// Define variable id and attribute and initialize them to theire default values.
unsigned int id{};
double attribute{};
// Here we will store all values (id, attribute) of all lines that we read in the follwing loop
std::unordered_map<unsigned, double> replacement{};
// Read in a llop ALL lines and extract id and attribute, and, check if this worked
while (file11 >> id >> attribute) {
// Create a new replacement value for id
replacement[id] = attribute;
}
// So, now, all data from file 11.txt is read and stored.
// We will now read the next file and store the data
// Open next input file NB.txt and check, if that worked
if (std::ifstream fileNB("NB.txt"); fileNB) {
// And already now, open output file 12.txt and check, if open worked
if (std::ofstream myfile("12.txt"); myfile) {
// Read a complete line and check, if that worked. Read all lines in a loop
for (std::string line; std::getline(fileNB, line); ) {
// Put the line in a std::istringstream, so that we can extract each single value
std::istringstream iss(line);
// We will store the single values of the just read line into a vector
// This we do, because we do not know, how many values will be in that line
// We use a so called iterator, to iterate over all elements in the just read line
// The result will be stored in a vector
// The istream_iterator will call the ">>"-operator, until the line is empty
// For the vector, we use its range constructor
std::vector values(std::istream_iterator<unsigned>(iss), {});
// Now go through all values, replace them and out the result into the output file
for (const unsigned& u : values) myfile << replacement[u] << " ";
myfile << "\n";
}
}
}
}
return 0;
}
Of course there are many other possible solutions

What could cause this error to create when using the array? Solution?

a bit new here, been back and forth trying to solve the issue of getline. Which I found the source of the error was due to intext[18]. Once I remove the array all errors go away. Problem is the document I have has 19 lines of data I need to retrieve so rather than typing out each string I decided to attempt to put it all in array. I am very new to c++ and this is the only time so far that I have hit a wall. I do apologize in advance if this has been solved. Ive been searching all day without resolve.
#include "pch.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <array>
using namespace std;
int main()
{
ifstream inFile;
string intext[18];
inFile.open("HW3_Data_W.txt");
while (inFile.is_open()) {
getline(inFile, intext);
cout << "Data from the file:" << endl;
cout << "Item 1: " << intext << endl;
break;
inFile.close();
}
}
You're trying to assign string value to string array variable, you should
getline(inFile, intext[i]);
where i is the number of line.
Also your array can only contain 18 lines of text, because you declared it this way. If you want to read files that have exactly 19 lines you should declare it this way:
string intext[19];
If you want your program to read any number of lines you should use std::vector.
Besides that, your while loop will only repeat once. because you break it unconditionally. I guess what you wanted to do is something like that:
inFile.open("HW3_Data_W.txt");
int i = 1;
while (inFile.is_open()) {
getline(inFile, intext[i]);
i = i + 1;
cout << "Data from the file:" << endl;
cout << "Item 1: " << intext << endl;
if(inFile.eof) continue;
inFile.close();
}
This code should work but is unnecessarily complicated. Your while condition checks if your file is open, but it will be open until you close it and you want to close it when you reach the end of the file. So your while condition look like that:
while (getline(inFile, intext[i]))
getline will return value that is convertible to false if it reaches last line of your file so your while will go until you read while file. And you have to check if file is open before your while, then you should close file after while. So something like that:
inFile.open("HW3_Data_W.txt");
int i = 0;
if(!inFile.is_open())
return EXIT_FAILURE;
while(getline(inFile, intext[i])) {
cout << "Item "<<i<<": " << intext[i] << endl;
}
inFile.close()
Some issues here:
If you have 19 lines to read, then the size of the string array should be at least 19.
Check if the file is opened successfully only once. No need to check in the while condition.
Read into consecutive elements of intext array within while using a counter which is initialized to 0 before the while loop. Increment this counter within the while loop.
Remove break from while as you want to read the whole file.
Do not close ifstream inside the while. Do it after the while loop.

C++ what's happening with my ifstream.get() function?

I'm trying to read in a picture file.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
ifstream read("C://Users/Ben/Desktop/1.jpg");
while (1){
cout << read.get();
cin.get();
}
return 0;
}
When I do this, I get a series of numbers ranging from 0 ~ 255. So I'm assuming it's reading in the byte values correctly, except for the fact that I hit -1 (eof) prematurely. After about 30 to 40 values, the -1 appears. It's a 3MB file. I don't expect the -1 to appear until way later. What's going on?
As #melpomene mentioned in their comment there may be a difference for the results of std::ifstream::get() regarding the file was opened using the std::ios::binary mode or not (at least for the Windows OS it seems).
There's no evidence that a value of -1 as result of std::ifstream::get() indicates that the read stream is in std::ifstream::eof() state. You may read up in the std::ifstream::get() reference documentation, for more information.
Try this:
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
// Add the mode ios::binary to make the file load in binary format.
ifstream read("C://Users/Ben/Desktop/1.jpg", ios::binary);
// Declare data variable
int data = 0;
// Reading loop
while (read.read((char*)&data, 4) && read.gcount() != 0) {
// Output data
cout << data << endl;
}
// Wait for user input before closing program
cin.get();
return 0;
}

Double spacing the same file in C++

I wrote some code in order to double space a file in C++, currently the program takes in one file and returns a different file, that is double spaced. I want the program to return the same file to the file directory. I'm pretty at this point I need to a use a temporary file, which is fine, but I would like to at the end of the program eventually return the same file(but double spaced to the user). Any help would be appreciated. Here is my code thus far.
#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;
int main( )
{
ifstream fin;
ofstream fout;
fin.open("story.txt");
if (fin.fail( ))
{
cout << "Input file opening failed.\n";
exit(1);
}
fout.open("numstory.txt");
if (fout.fail( ))
{
cout << "Output file opening failed.\n";
exit(1);
}
char next;
int n = 1;
fin.get(next);
fout << n << " ";
while (! fin.eof( ))
{
fout << next;
if (next == '\n')
{
fout << endl;
}
fin.get(next);
}
fin.close( );
fout.close( );
return 0;
}
As you suggest, create a temporary file and then, only when processing has been successful, remove the existing file and rename the temporary file.
By the way, putting using namespace std at the top of every program is a bad habit that you'd do well to avoid.
Simplest solution: delete the input file and rename the new one (remove and rename)
Better solution: open the first file for both reading and writing (fstream) and replace the content with a stringstream buffer without even creating a temporary file (also faster).
You have plenty of choices.

Reading integers from a file returns incorrect output (ifstream)

In my attempt to make an automatic Sudoku solver in C++, the first step I need is to read the 9x9 grid from a file. Currently I just try to simply read the data, and display it as output, however the output is not correct. My code is as following:
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main() {
// Initialize string for the lines to be read in
string line;
// Create the object to read the file "data.txt"
ifstream sudokuData("data.txt");
// Check if file opened properly
if (!sudokuData.good()) {
cout << "Couldn't open the file.\n";
}
// Read only if file exists
if ( sudokuData.is_open() ) {
cout << "Starting to read from file... \n";
// Read as long as there are lines in the file
while ( getline(sudokuData,line) ) {
cout << line << '<\n';
}
// Close file once done reading
sudokuData.close();
} else {
// If file cannot be read, inform the user
cout << "Unable to open file";
}
return 0;
}
Which from all I can find, is correct. The data file contains the numbers from 1 to 9 in each row, separated by a space. An example line would be:
1 2 3 4 5 6 7 8 9
But when I run the code, I get the following output:
Starting to read from file
153709 1 2 3 4 5 6 7 815370
RUN SUCCESSFUL (total time: 38ms)
What the heck am I doing wrong?
I'm using NetBeans 8.0 as IDE, if that is of any use...
There is a typo in your code. At line 27 you define a multi-byte char constant with '<\n'. Remove the < sign and it should work fine.