how to get rid of blank line in c++? - c++

I'm trying to fill text document, but when I do - I get first line blank.
My text document, I'm reading from, looks like this:
3
first fr random 5
second 9
third shazam 2
I've tried removing first value and so blank line went away. So it correlates, but I need that value.
// My code
ifstream in("U2.txt");
ofstream out("U2.txt");
int n;
in>>n;
char vardaiStart[n][21];
in.read(vardaiStart[0], 21);
out << vardaiStart[0]<< endl;
output looks like this:
*blank*
first fr random
but what I want is:
first fr random
So, in other projects I won't be using old C since now, but for this project I red that [endline] and ignored it like this: in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');

Your input file looks like:
3[endline]
first fr random 5[endline]
second 9[endline]
third shazam 2[endline]
Note the [endline] I added: they can be '\n', '\r\n' depending on the system that generated the file.
Your first instruction is:
in >> n;
a formatted input read: you are asking to read an integer from the file, so only characters that can form valid integers will be read.
This means that after that instruction the remaining portion of the file will be:
[endline]
first fr random 5[endline]
second 9[endline]
third shazam 2[endline]
The rest of your code reads raw bytes, so it will read the first [endline] as well (and print it).
As other suggested in the comments, you should not be using variable length arrays as they are not part of any C++ standard (but part of the C one). Try to use the C++ standard library instead.

Related

C++ getline in for loop

I learn to program in c++ with previous experience with python and R. Id say I understand for loops well, but now I found out that I do not know nothig about them. Here is piece of code.
for (int i = 0; i != 1; ){
string name;
getline(infile, name);
if (name == end_input){
i = 1;
}
else{
names.push_back(name);
}
}
Whole program should (and do) read names (name) from file infile and store them into names string. Than I want them to store in another file. When I look on the code, I would thing c++ do following instructions:
create integer i and set it to 0
create string name
read the line from infile and store this line into names string vector.
this will repeat unless name == end_input
From this I would say that c++ will store first line in input file again and again because I didnt tell him to jump to next line after getline the first line. But program reads all names from that file, line by line as expected by author. How is that possible?
Thank you.
getline automatically moves to the next line after reading a line.
Also a do while loop might serve your purposes better here.
When an inbuilt function does not behave as you expected, the logical next step should be to check the Documentation. If you do, you will see the following:
Extracts characters from is and stores them into str until the delimitation character delim is found (or the newline character, '\n', for (2)).
The extraction also stops if the end of file is reached in is or if some other error occurs during the input operation.
If the delimiter is found, it is extracted and discarded (i.e. it is not stored and the next input operation will begin after it).
Which answers your Question.

Parsing a tab delimited text file

I'm trying to parse a text file from one format to another. The text file is delimited by tabs. The text file I'm using as test has as of now three types of lines. For example, the first line of the text file has an H in the beginning. Since I do not need it now, I ignore it and pass to the next line. Similarly, I have lines that start with S and L. The S lines have five strings, including the first character, which are read by:
while(std:: ifstream readFile >> string1 >> string2 >> string3)
Below this while I have an if statement to check every S at the beginning of each line, which is as follows:
if(string1[string1.length()-1]=='S')
Then I print in the console each value to make sure every line which has an S is being printed in the console, but it's not. It's showing n - 2 where n = total of lines containing S at the beginning. I should also mention that below print statement, I also have this: std::getline(readFile, string1); without this, it shows me n - 5, if I'm not mistaken.
Also, when I only use two parameters while instead of three, all lines are shown with the first two strings, but as soon as I pass three parameters it changes back to n - 2.
What could be the problem that whenever I pass more than two parameters, it does not show me every line that contain S at the beginning(specifically the first two).
Thanks, and sorry if not explicit enough.

C++ Easy way to ignore first word of input

I am writing a program to read a text file line by line, store the line values in a vector, do some processing then write back to a new text file. This is what the text file typically looks like:
As you can see, there are two columns: one for the frame number and another for the time. What I want is only the second column (aka the time). There can be hundreds, if not thousands of lines in the text file. Previously I have been manually deleting the frame number column which i'd rather not do. So my question is: is there an easy way to edit my current code so that when I read the file with getline() it skips the first word and only gets the second? Here is the code that I use to read the text file. Thanks
ifstream sysfile(sys_time_dir);
//Store lines in a vector
vector<string> sys_times;
string textline;
while (getline(sysfile, textline))
{
sys_times.push_back(textline);
}
Since you have two numbers in each line, you can read two numbers and ignore the first number.
vector<double> sys_times;
int first;
double second;
while ( sysfile >> first >> second )
{
sys_times.push_back(second);
}
std::string ignore_me;
while (sysfile >> ignore_me, getline(sysfile, textline)) {
...
This utilizes the comma operator, reading in the first word (here defining "word" as a continuous sequence of non-space characters) of the line, but ignoring the result, then using getline to read the rest of the line.
Note that for the specific data format you describe, I would rather choose what RSahu showed in their answer. My answer is more general to the problem of "skipping the first word and reading the rest of the line".

Strange error printing getline() strings in cout

I was trying to test my classes when I encountered a weird problem in the input of test cases.
I tried to simplify the input to see what went wrong so I created the program below.
#include <iostream>
#include <string>
int main()
{
std::string number;
while (std::getline(std::cin, number))
{
std::cout << std::string(number) << " ";
}
}
Basically, I am getting each line of text and storing it in a string variable using getline(). Then I display each string using std::cout and append a single space character.
My input file contains this:
one six
one seven
The expected output should be like this:
one six one seven
But instead, I get this:
one seven
That is a space character followed by the second line of the input. It disregards the first line of input. I know for a fact that each line are being read properly because they were correctly displayed when I replaced the code with this:
std::cout << std::string(number) << std::endl;
This error is quite new to me. What's happening here? Can anybody explain? TIA!
Ok, its clear.
Your input file must be : one six\r\ntwo seven\r\n with normal Windows EOL.
When you read it under cygwin, you get in first read one six\r, only the \n being eaten by getline, and same one seven\r on the second line.
So you write : one six\r one seven\r (with an ending blank). But the \r alone put the curson back in first column of same line and second line erases first.
And normally the problem is not visible if you replace the ending blank by a std::eol that puts the cursor on a new line. The tab (\t) if really a special case : it put the cursor on eighth column exactly where you expect it, but by pure chance. If you invert the two lines it would be more apparent because you would see the remaining of first line at end of second.
You can confirm it by writing the output to a file and editing it.
I could reproduce it under Linux with a Windows EOL. The reason for that is that Cygwin closely mimics Unix-Linux and use Unix EOL convention of only \n.

c++ overwriting file data?

I am trying to run a program to replace certain data within a file. The relevant parts of the file attempting to be replaced look like the following:
1 Information 15e+10
2 Information 2e+16
3 Information 6e+2
And so on.
The files in question can be very large in the multiple gigabyte range and to my understanding because of this using a buffer of the whole file and rewriting the whole file is impossible/unreasonable. Well that is all fine I just want to replace the values (ex. the 15e+10).
This all works fine with simple ios::in|ios::out and tellp() if I am replacing the value with a similar sized value (15e+10->12e+12) or even if its a smaller size as I can simply add an extra space which can be ignored down the line (ex. 15e+10->4e+10 ). But I am running into the problem if I need to replace the value with a value whose length is longer than already in the file (ex. 6e+2->16e+10) it will write over the new line character or start writing over the information in the next line.
I have searched on the forums and everyone says you can either overwrite in the file, you can append to the end of the file, or you can buffer and recreate the whole file. Is there anyway I can achieve my goal of overwriting the value correctly without having to recreate the file?
If not then how can I have 2 files open (1 input 1 output) to do this if multiple files in question are too large for the memory?
Note: I would also like to avoid using boost:: as I need to be able to run this on a system without the boost library.
Open a stream to read from the input (IN) file and a second stream (OUT) to write to a new output (tmp) file.
Read from IN and write to OUT. When you get a value from IN that you want to replace write the replacement to OUT instead of the value you got from IN.
When parsing is complete replace the first file with the second (tmp) file.
Would this work for you?
Use lseek()/fseek() for "jump" to a given position in a file.
You can use seekp to go to the location and rewrite it with <<
Example:
example.txt ( |?| = 1 byte of data )
|A|B|C|\n|1|2|3|D|E|F|\n|4|5|6|
//Somewhere in the code
fstream file;
open("example.txt");
//Somehow find the character distance and store it into "distance"
seekp(distance);//If distance = 0, it will go to "A" like rewind() but easier for me
If the distance is 4, the next character will be overwritten is 1
file << "987";
And the file will be
|A|B|C|\n|9|8|7|D|E|F|\n|4|5|6|
BUT the only problem here is when you need to increase/decrease the size:
Increase:
You will overwrite the other character so you need to create a temp string to store it the rest of data or separate it into smaller chunk if the data is too large like
|A|B|C|\n|9|8|7|D|E|F|\n|4|5|6|
string tempstring;
seekp(distance);
file >> tempstring;
seekp(distance);
file << content << tempstring; //content is the data
Decrease:
The easiest solution is to write NULL character \0 to the excess space like
|A|B|C|\n|1|\0|\0|D|E|F|\n|4|5|6|
The only side-effect is the file size is the same as before