I have a data file that I am trying to input and the data is split into sections via a blank line. The data will be read in from a text file.
How do I make my code skip a blank line to read in the next piece of data? I am currently just in the planning stages of my application.
I'm a beginner so I'm not really sure how to go about this.
Can anyone advise a method on how to approach this?
I have just written it out and my code looks like this:
string ship2_id;
char ship2_journey_id[20];
float ship2_l;
int ship2_s;
getline(itinerary_file, ship2_id);
if (ship2_id = ' ')
{
itinerary_file.ignore(numeric_limits<streamsize>::max(), '\n');
}
else
getline(itinerary_file, ship2_id);
cout << ship2_id << endl;
Yes,
stream.ignore(max_number_of_chars_to_be_skipped, '\n');
I usually just use 1ul<<30 or similar for the first parameter, but
this could be a DoS vector if the input is untrusted and slow to skip those chars
the "pedant" value would read std::numeric_limits<std::stream_pos>::max() or similar
I don't what are you using to read the file, but, to search for a blank line, look for two "line breaks" together. Take in account that the "line breaker" character is different for some OS. In Windows, by default, there are two characters that are used together for a line break.
Related
Sorry, the wording for the actual question is probably wrong. I have a program that reads in a line from a .txt file and then puts the string into an object to compare it to a string entered by the user. I haven't been able to get it to match, and when I've tried to see what is entered, I don't see much. Maybe there's an invisible character denoting the end of the line? I've tried code like this:
std::cout << "...." << table[row][col]->get() << "...." <<std::endl;
And got
....a
as the result. When reading the file I used std::getline() if that makes a difference.
I didn't find a true fix, although I did see that the length of the read-in string was one int longer than the actual word. I was able to use a substring to cut the end off of the string.
I need to create a program that reads strings from two different files and write these strings on a new file. The thing is, it must alternate both files, meaning that it should write a line from one file, and then one line from the other, and so on.
I'm having a problem with my code, it writes the first line of the first file, and then it writes all lines from the second file.
Anyone knows how to solve this problem?
do {
getline(archivo1, sLinea);
archivoS << sLinea << endl;
getline(archivo2, sLinea2);
archivoS << sLinea2 << endl;
} while (!archivo1.eof() && !archivo2.eof());
The code looks correct and should work under normal circumstances. This might be a problem with the encoding of the second file, where the newline characters are not being recognised as such on your platform, which could result in the entire second file being interpreted as a single line by the C++ standard library.
Windows (CR+LF), Unix/Linux (LF), and Mac (CR) each have different conventions for newlines. Search about the carriage return and line feed characters across platforms to learn more about this topic.
To identify if this is the issue, try running the code on two separate copies of the first file to see if it produces the expected output?
If newline encoding is your issue, you will either need to convert the second file to use your platform's newline encoding (you can use a tool like Notepad++ to easily do this) or incorporate logic which controls for this into your program.
Check your second file. In all likelihood it does not contain the line delimiter "\n" , per line. There may be only one at the end
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".
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.
Suppose I have the following text:
My name is myName. I love
stackoverflow .
Hi, Guys! There is more than one space after "Guys!" 123
And also after "123" there are 2 spaces and newline.
Now I need to read this text file as it is. Need to make some actions only with alphanumeric words. And after it I have to print it with changed words but spaces and newlines and punctuations unchanged and on the same position. When changing alphanumeric words length remains same. I have tried this with library checking for alphanumeric values, but code get very messy. Is there anyother way?
You can read your file line-by-line with fgets() function. It will fill char array and you can work with this array, e.g. iterate over this array, split it into alnum words; change the words and then write fixed string into new file with "fwrite()" function.
If you prefer C++ way of working with files (iostream), you can use istream::getline. It will save spaces; but it will consume "\n". If you need to save even "\n" (it can be '\r' and '\r\n' sometimes), you can use istream::get.
Maybe you should look at Boost Tokenizer. It can break of a string into a series of tokens and iterate through them. The following sample breaks up a phrase into words:
int main()
{
std::string s = "Hi, Guys! There is more...";
boost::tokenizer<> tok(s);
for(boost::tokenizer<>::iterator beg = tok.begin(); beg != tok.end(); ++beg)
{
std::cout << *beg << "\n";
}
return 0;
}
But in your case you need to provide a TokenizerFunc that will break up a string at alphanumeric/non-alphanumeric boundaries.
For more information see Boost Tokenizer documentation and implementation of an already provided char_separator, offset_separator and escaped_list_separator.
The reason that your code got messy is usually because you didn't break down your problem in clear functions and classes. If you do, you will have a few functions that each do precisely one thing (not messy). Your main function will then just call these simple functions. If the function names are well chosen, the main function will become short and clear, too.
In this case, your main function needs to do:
Loop: Read every line of a file
On every line, check if and where a "special" word occurs.
If a special word occurs, replace it
Extra hints: a line of text can be stored as a std::string and can be read by std::getline(std::cin, line)