C++ the first cout will not be printed - c++

As you can see, I have a cout here before the loop starts. Seekg starts at the beginning and the first word in the txtfile is "Hello". But it doesn't print it out(the first cout).
When I remove the while loop, then its not a problem, the first word gets included in the output.
The first "cout", shouldn't it be printed out no matter what comes after it? How is it possible that next lines of code(THIS case) affects the previous "cout" above it ?
int main()
{
string a;
ifstream myfile;
myfile.open("test.txt");
myfile.seekg(0);
getline(myfile,a);
cout << a << endl;
int z = 0;
while( a != "x" ) {
myfile.seekg(z);
getline(myfile,a);
z += a.size() + 2;
cout << a << endl;
}
}
I Also should mention that the file starts with "hello", AND contains 600 newlines and a word on every new line. The last line contains "x".
[EDIT]
Here's another example. I belive this will be helpful. This is my code now:
int main() {
string a;
ifstream myfile;
int newpos = 0;
myfile.open("example.txt");
myfile.seekg(newpos);
getline(myfile,a);
while (a != "x") {
myfile.seekg(newpos);
getline(myfile,a);
cout << a << endl;
newpos += a.size() + 2;
}
}
This is my textfile:
hello
johan
nils
erik
john
x
The output is exactly as it looks in the textfile above.(so far so good).
BUT, then I add about 600 new names to the list/textfile(same structure as above, no changes there, just new names added). Only ONE "hello" at the top so I can track the start, and one x at the end.
This still works with around 100 new names, hello is still printed out in the beginning. But when i add around 600 new names , hello will not be included(the very first cout). Why is that?

But when I add around 600 new names, hello will not be included (the very first cout).Why is that?
Looks like your Screen Buffer Size wasn't big enough to show all of the buffer lines. So when the number of printed lines exceeds a specific height, the console starts to ignore the previously printed lines which result you think it didn't print them all.
Since you're using Windows you can try to increase it as so
For all console apps
Right-click the title of the console and choose Defaults
go to Layout tab
Under the Screen Buffer Size, Increase the Height to (i.e 9001)
Click OK then restart the console
For a specific app
Right-click the title of the console and choose Properties
go to Layout tab
Under the Screen Buffer Size, Increase the Height to (i.e 9001)
Click OK.
Note that the Default Height in most Windows Operating systems is 9001.

Related

Trying to read from a text file to an object array

so guys i have to create 5 job objects from the information from a text file which looks like this
A 0 3
B 2 6
C 4 4
D 6 5
E 8 2
the left column is its name, the next is arrival time, and the final one is the duration
this is what i have right now
#include <iostream>
#include <fstream>
#include "Job.hpp"
using namespace std;
int main(int argc, const char * argv[]) {
string fileinfo;
string programname;
//gets Jobs.txt from commandline
programname.append(argv[1]);
Job jobs[5];
fstream afile;
//reads in from the file to create job objects
afile.open(programname);
if(afile.fail()){
cout <<"file could not be opened " << programname <<endl;
}
while(!afile.eof())
{
getline(afile,fileinfo);
int i = 0;
//cout <<fileinfo[0] <<endl;//gets next letter
//cout <<fileinfo[2] <<endl;//gets next arrival time
//cout << fileinfo[4] <<endl;//gets next duration time
jobs[i].setletter(fileinfo[0]);
jobs[i].setarrivaltime(fileinfo[2]);
jobs[i].setduration(fileinfo[4]);
i++;
}
afile.close();
cout << jobs[1].getletter() <<endl;
cout << jobs[2].getletter() <<endl;
cout << jobs[3].getduration() <<endl;
right now when i go in and print out the values in my different objects(like at the bottom of the code)after i close the file they all contain the information from the first line of the file.
i dont know why because technically i increase 'i' after i set all the values of the job and then fileinfo gets the nextline of the file, so this to me seems like it should work.
But like the values i get from those 3 couts at the bottom the results are
A
A
0
the Job class
Job::Job(){}
Job::Job(char let, int arrive, int dura){
letter = let;
arrivaltime = arrive;
duration = dura;
}
and it also has all its get and sets defined
so can u guys please help me be able to read in from the file correctly and create my object array
int i = 0;
Each time through the loop, i gets initialized to zero. Immediately after initializing i to 0, your code does this:
jobs[i].setletter(fileinfo[0]);
jobs[i].setarrivaltime(fileinfo[2]);
jobs[i].setduration(fileinfo[4]);
i will always be zero, here. This is what you're seeing. Your computer will always do exactly what you tell it to do, instead of what you want it to do. This is a good rule of thumb for you to keep in mind, going forward.
i++;
This doesn't matter, because on the next iteration of the while loop, i will be initialized to 0 again. See above.
while(!afile.eof())
And, this is going to be your second bug, also, which you will immediately discover after fixing your first bug (initialize i before the loop, not inside it).

Getting only partial output

I wrote a C++ program to print out the multiplication of all two digit numbers.
I am getting only partial output of some product and not the entire output.
Code:
int main()
{
int ans;
for (int i = 10; i <= 99; i++) {
for (int j = 10; j <= 99; j++) {
ans = i * j;
cout << ans << endl;
}
}
cin.get();
return 0;
}
The output starts from 6816 (instead of 10*10=100) upto 9801 (which is 99*99).
On the other hand if I do the same for single digits, the output is correct.
There are 299 numbers between 6801 and 9899 (both inclusive) printed from this program, so it seems you are using Command Prompt of Windows to view the result.
If so, to view all numbers in the window,
Right-click the window icon in upper left
Select "property"
Select "layout" tab
Set "height" in "buffer size of screen" to a large number such as "9999".
(The name of menus might not be correct because I am using Japanese OS)
Alternatively, you might want to use redirect to put the output into a text file.
Aside from missing #include and using namespace std; lines you did not post, there is nothing wrong with your program.
The output is 8100 lines long, are you sure you can see all these lines in your terminal? Try redirecting the output to a file and load this file into an editor to verify the number of lines.

Logic for reading rows and columns from a text file (textparser) C++

I'm really stuck with this problem I'm having for reading rows and columns from a text file. We're using text files that our prof gave us. I have the functionality running so when the user in puts "numrows (file)" the number of rows in that file prints out.
However, every time I enter the text files, it's giving me 19 for both. The first text file only has 4 rows and the other one has 7. I know my logic is wrong, but I have no idea how to fix it.
Here's what I have for the numrows function:
int numrows(string line) {
ifstream ifs;
int i;
int row = 0;
int array [10] = {0};
while (ifs.good()) {
while (getline(ifs, line)) {
istringstream stream(line);
row = 0;
while(stream >>i) {
array[row] = i;
row++;
}
}
}
}
and here's the numcols:
int numcols(string line) {
int col = 0;
int i;
int arrayA[10] = {0};
ifstream ifs;
while (ifs.good()) {
istringstream streamA(line);
col = 0;
while (streamA >>i){
arrayA[col] = i;
col++;
}
}
}
edit: #chris yes, I wasn't sure what value to return as well. Here's my main:
int main() {
string fname, line;
ifstream ifs;
cout << "---- Enter a file name : ";
while (getline(cin, fname)) { // Ctrl-Z/D to quit!
// tries to open the file whose name is in string fname
ifs.open(fname.c_str());
if(fname.substr(0,8)=="numrows ") {
line.clear();
for (int i = 8; i<fname.length(); i++) {
line = line+fname[i];
}
cout << numrows (line) << endl;
ifs.close();
}
}
return 0;
}
This problem can be more easily solved by opening the text file as an ifstream, and then using std::get to process your input.
You can try for comparison against '\n' as the end of line character, and implement a pair of counters, one for columns on a line, the other for lines.
If you have variable length columns, you might want to store the values of (numColumns in a line) in a std::vector<int>, using myVector.push_back(numColumns) or similar.
Both links are to the cplusplus.com/reference section, which can provide a large amount of information about C++ and the STL.
Edited-in overview of possible workflow
You want one program, which will take a filename, and an 'operation', in this case "numrows" or "numcols". As such, your first steps are to find out the filename, and operation.
Your current implementation of this (in your question, after editing) won't work. Using cin should however be fine. Place this earlier in your main(), before opening a file.
Use substr like you have, or alternatively, search for a space character. Assume that the input after this is your filename, and the input in the first section is your operation. Store these values.
After this, try to open your file. If the file opens successfully, continue. If it won't open, then complain to the user for a bad input, and go back to the beginning, and ask again.
Once you have your file successfully open, check which type of calculation you want to run. Counting a number of rows is fairly easy - you can go through the file one character at a time, and count the number that are equal to '\n', the line-end character. Some files might use carriage-returns, line-feeds, etc - these have different characters, but are both a) unlikely to be what you have and b) easily looked up!
A number of columns is more complicated, because your rows might not all have the same number of columns. If your input is 1 25 21 abs 3k, do you want the value to be 5? If so, you can count the number of space characters on the line and add one. If instead, you want a value of 14 (each character and each space), then just count the characters based on the number of times you call get() before reaching a '\n' character. The use of a vector as explained below to store these values might be of interest.
Having calculated these two values (or value and set of values), you can output based on the value of your 'operation' variable. For example,
if (storedOperationName == "numcols") {
cout<< "The number of values in each column is " << numColsVal << endl;
}
If you have a vector of column values, you could output all of them, using
for (int pos = 0; pos < numColsVal.size(); pos++) {
cout<< numColsVal[pos] << " ";
}
Following all of this, you can return a value from your main() of 0, or you can just end the program (C++ now considers no return value from main to a be a return of 0), or you can ask for another filename, and repeat until some other method is used to end the program.
Further details
std::get() with no arguments will return the next character of an ifstream, using the example code format
std::ifstream myFileStream;
myFileStream.open("myFileName.txt");
nextCharacter = myFileStream.get(); // You should, before this, implement a loop.
// A possible loop condition might include something like `while myFileStream.good()`
// See the linked page on std::get()
if (nextCharacter == '\n')
{ // You have a line break here }
You could use this type of structure, along with a pair of counters as described earlier, to count the number of characters on a line, and the number of lines before the EOF (end of file).
If you want to store the number of characters on a line, for each line, you could use
std::vector<int> charPerLine;
int numberOfCharactersOnThisLine = 0;
while (...)
{
numberOfCharactersOnThisLine = 0
// Other parts of the loop here, including a numberOfCharactersOnThisLine++; statement
if (endOfLineCondition)
{
charPerLine.push_back(numberOfCharactersOnThisLine); // This stores the value in the vector
}
}
You should #include <vector> and either specific std:: before, or use a using namespace std; statement near the top. People will advise against using namespaces like this, but it can be convenient (which is also a good reason to avoid it, sort of!)

Save/Load workspace in C++ application

I'm working on adding a new feature to an existing program. It's basically a save/load workspace feature, where a user can save the positions of their windows, and then load said positions whenever they want to by selecting a menu item. In order to implement this, I have created code which extracts the screen coordinates of the window and writes them to a file (below) :
void CMainFrame::SaveWorkspace()
{
RECT ctrlsize;
m_pDialog->GetWindowRect((LPRECT)&ctrlsize); //obtains location for window
ofstream Workspace("saveone", ios::out);
Workspace << ctrlsize.left << "," << ctrlsize.top << "," << ctrlsize.right << "," << ctrlsize.bottom;
}
And this (is supposed to) loads the workspace:
void CMainFrame::LoadWorkspace()
{
//Read in the data from the file
int data[3][4];
int r=0;
int a=0;
int b=0;
ifstream infile;
infile.open("saveone");
for(a = 0; a< 3; a++)
{
for(b = 0;b<4;b++)
{
infile >> data[a][b];
cout << data[a][b];
}
}
infile.close();
//Now, assign the extracted values
RECT ctrlset;
ctrlset.top = data[0][1];
ctrlset.left = data[0][0];
ctrlset.right = data[2][0];
ctrlset.bottom = data[0][3];
// Finally, reassign the window positions
m_pDialog->SetWindowPos(NULL, ctrlset.left, ctrlset.top, (ctrlset.right - ctrlset.left), (ctrlset.bottom - ctrlset.top), SWP_SHOWWINDOW);
}
Problems:
1) the SaveWorkspace function works sporadically; more often than not, it doesn't create a file.
2) the LoadWorkspace function doesn't work. Specifically, only the data[0][0] coordinate gets saved to the array (the first value in the file).
This seems like a fairly easy thing to do, I'm a bit embarrassed that it's giving me so much trouble...
EDIT: I've fixed problem #1. Now I just need to figure out why my array isn't working.
You have at least two problems in the reading.
Your array definition is wrong. It is :
data[2][3];
This has only 6 values.
However, in the loop you are reading 12 values out.
You have the "," values in the file. You are not getting rid of them.
Maybe as an easy solution, you could add a new line after each entry when you write them.
Or you could enter the details of a single rectangle on one line, then read the full line and parse for the individual components yourself.

Binary file only overwrites first line C++

So I have a binary file that I create and initialize. If I set my pointer to seekg = 0 or seekp = 0, then I can overwrite the line of text fine. However if I jump ahead 26 bytes (the size of one line of my file and something I have certainly confirmed), it refuses to overwrite. Instead it just adds it before the binary data and pushes the old data further onto the line. I want the data completely overwritten.
char space1[2] = { ',' , ' '};
int main()
{
CarHashFile lead;
lead.createFile(8, cout);
fstream in;
char* tempS;
tempS = new char[25];
in.open("CarHash.dat", ios::binary | ios::in | ios::out);
int x = 2000;
for(int i = 0; i < 6; i++)
tempS[i] = 'a';
int T = 30;
in.seekp(26); //Start of second line
in.write(tempS, 6); //Will not delete anything, will push
in.write(space1, sizeof(space1)); //contents back
in.write((char *)(&T), sizeof(T));
in.write(space1, sizeof(space1));
in.write(tempS,6);
in.write(space1, sizeof(space1));
in.write((char *)&x, sizeof(x));
//Now we will use seekp(0) and write to the first line
//it WILL overwrite the first line perfectly fine
in.seekp(0);
in.write(tempS, 6);
in.write((char*) &x, sizeof(x));
in.write(tempS, 6);
in.write((char *) &T, sizeof(T));
return 0;
}
The CarHashFile is an outside class that creates a binary file full of the following contents when create file is invoked: "Free, " 1900 ", Black, $" 0.00f.
Everything enclosed in quotes was added as a string, 1900 as an int, and 0.00f as a float obviously. I added all of these through write, so I'm pretty sure it's an actual binary file, I just don't know why it only chooses to write over the first line. I know the file size is correct because if I set seekp = 26 it will print at the beginning of the second line and push it down. space was created to easily add the ", " combo to the file, there is also a char dol[1] = '$' array for simplicity and a char nl[1] = '\n' that lets me add a new line to the binary file (just tried removing that binary add and it forced everything onto one row, so afaik, its needed).
EDIT: Ok so, it was erasing the line all along, it just wasn't putting in a new line (kind of embarrassing). But now I can't figure out how to insert a newline into the file. I tried writing it the way I originally did with char nl[1] = { '\n' }. That worked when I first created the file, but won't afterwards. Are there any other ways to add lines? I also tried in << endl and got nothing.
I suggest taking this one step at a time. the code looks OK to me, but lack of error checking will mean any behavior could be happening.
Add error checks and reporting to all operations on in.
If that shows no issues, do a simple seek then write
result = in.pseek(26);
//print result
result = in.write("Hello World",10);
// print result
in.close();
lets know what happens
The end problem wasn't my understand of file streams. It was my lack of understanding of binary files. The newline screwed everything up royally, and while it could be added fine at one point in time, dealing with it later was a huge hassle. Once I removed that, everything else fell into place just fine. And the reason a lot of error checking or lack of closing files is there is because its just driver code. Its as bare bones as possible, I really didn't care what happened to the file at that point in time and I knew it was being opened. Why waste my time? The final version has error checks, when the main program was rewritten. And like I said, what I didn't get was binary files, not file streams. So AJ's response wasn't very useful, at all. And I had to have 25 characters as part of the assignment, no name is 25 characters long, so it gets filled up with junk. Its a byproduct of the project, nothing I can do about it, other than try and fill it with spaces, which just takes more time than skipping ahead and writing from there. So I chose to write what would probably be the average name (8 chars) and then just jump ahead 25 afterwards. The only real solution I could say that was given here was from Emile, who told me to get a Hex Editor. THAT really helped. Thanks for your time.