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.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm creating a simple directory program that allow user to enter a file name and search that file by name, address, or phone number. I'm having trouble properly reading the file.
If someone could give me suggestions on how to fix my getFirstName function. The function should read the first word of the file.
Example file:
Bob Smith 123456789
123 Main Street
Susan Smith 1224445555
543 Market Street
Here is part of my code so far.
string file;
string first;
int main() {
ifstream inFile;
cout<<"Enter file name: ";
cin>> file;
inFile.open(file);
if(inData.fail()) {
cout<<"INVAILD";
}
getFirstName(first);
}
void getFirstName(string f, inFile file) {
file.open(f);
while(file.good(f)) {
file>>f;
}
if (file.bad()) {
cout<<"Name not found";
}
}
i will not write you the program, but let me point you in a direction.
first of all: please format your code better. maybe its just because stackoverflow, but there should be consistent and sensefull formatting of your code, otherwise you and others cant read it well and have trouble finding problems. (plz google clang-format for a tool, maybe an ide would do it as well).
split your programm in different logical parts. my approach would be:
open file, if not possible give warning, end program
read file content into a string IN: filename, OUT: string of content
split the string into line, IN: string, OUT: std::vector
for each line, split the line into parts(3 elements?) IN: linestring, OUT: name, street, ...
You can that in proper datastructures, plz see the STL for good ones
Access your datastructure for the wanted information.
Proposal for your data.
istream for file, you have that
std::string for file content
std::vector for line wise filecontent
std::unordered_map map the name to information.
this should give you a googling start. each subproblem can be solved independent (and tested) and is easier to find on SO :)
Good luck.
I agree with the comments. Yet to answer your issue "The function should read the first word of the file." below is a general idea how you can read the first word from file:
...
ifstream inFile; // define your input stream
string firstwrd; // first word
inFile.open("yourfile"); // open your file
inFile>> firstwrd; // this will read the first word
inFile.close(); // close the file
...
And please consider reading through Jonas`s comments.
Edit: Please note my answer by no means is the definitive tutorial of best practices of reading from file. It applies your specific case.
HTH!
Before you can even begin to start programming, you have to identify the exact format of the file you want to read. That format gives you the order of operations for how you intend to read from the file.
In your example, you give:
Bob Smith 123456789
123 Main Street
Susan Smith 1224445555
543 Market Street
Which is broken down into a by-line format of:
[First Name] [Last Name] [User ID (I assume)]\n
[Address]
So now that we have that established, the first thing we do is open the file stream.
ifstream file("path\\to\\file");
When it comes to retrieving information from a file stream, there are 2 standard methods: the >> operator and getline().
The >> operator returns the very next block of text in a given fstream up to any whitespace character such as space, newline or return characters. The syntax for this is file >> var where file is the fstream you intend you read from and var is the variable you want to write to.
The getline() function will return the entire line, including spaces, but will stop at return and newline characters. The actual syntax of the function is std::getline(read, write); where read is the file stream or string you intend to actually read from and write is the variable you intend to copy the real line to.
For example:
ifstream file("file.txt");
string firstname, lastname, id, address;
file >> firstname; //get the first word of the file.
file >> lastname; //get the second word of the file.
file >> id; //get the third word of the file.
getline(file, address); //Get the next whole line of the file, regardless of how many words.
A funny quirk is that you don't have to worry about manually telling C++ where in the file you're wanting to look for the data. As the file is read a pointer is automatically kept inside of the file stream of where to begin reading from next. When you get one word, the pointer automatically starts at the beginning of the next word, so you just keep pulling data linearly until you reach the end of the file.
void getFirstName(string f, inFile file); should be void getFirstName(string f, ifstream inFile);.
And remember, put an ampersand (&) between the type of the variable and the name to avoid creating a copy of the file (that consumes more ram), not putting the ampersand is only reasonable to use if you want to make changes to the variable that should not stick around.
And where is string f defined? You call the function without passing f but it's used in the function. That is a serious problem.
The ifstream.good() function if I remember correctly can't take parameters.
If you're trying to find f (you didn't tell us what it is so I can't be more precise) then you should first understand that f should be a file (since you used file.open(f);), pass the value to a string, and after doing inFile >> name_of_your_string; do if (name_of_your_string == f) { /* the last word read corresponds to f */}.
The type is ifstream, and the variable's name is inFile.
Also since getFirstName is defined after main, you got to put this before main void getFirstName(string f, ifstream inFile); this is called a prototype, and it tells the compiler that the function is after main.
Obviously don't remove the rest of the function. If that's a problem for you move main under it. Also if someone puts a space in the input everything before the last space will be lost, remove cin >> file; and use getline (cin, file);
Remember to update the answer with more details on what f is and what exactly you want it to do.
EDIT: Remember to use inFile.close(); after you stop reading the file to avoid subtle errors.
So I'm trying to go through input line by line. Each line in the input is formatted like this:
Words_More words_even more words_What I Need to Go Through_ Random_ Random_Etc.
With a random amount of word clusters (The words separated by '_')
I want, for each line, to be able to ignore all the words until I get to the fourth word cluster which in the example I gave would be: "What I Need To Go Through" and then store those separate words in some data structure that I haven't decided upon yet.
My first thought would be to use
getline(cin, trash, '_');
three times and deal with the data that follows, but then how would I loop line by line until the end of the input?
You basically have two options:
use getline for each line, then parse it
use getline(stream, string) to get a line from your stream, and store it into a string. Then construct an istringstream to parse this again (with the getline you thought of.
get what you need, and then ignore() stuff unill the next newline
You do getline() thing, and then you call ignore() (doc)
to read and discard the rest of the line, so you can start again with the next line.
which one you use is up to you. but the second one has slightly better performance, if you care about that stuff.
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 would like to figure out how to read a whole line (including spaces) with std::cin. I am aware of the existence of std::getline, I would just like to figure out how to do it with std::cin so I can better understand iostream in C++. I've tried using a for loop with std::cin, however it keeps reading past the end of the line. Any help would be greatly appreciated.
Also the cin << only allows us to enter one word into a string.
However, there is a cin function that reads text containing blanks.
std::cin.get(name, MAX);
get will read all characters including spaces until Max characters have been read or the end of line character (ā\nā) is reached and will put them into the name variable.
You should decide what is MAX.
I need to read in a string and then an integer until the user indicates end of input (ctrl-d in linux). Again, I am stuck. Currently I have a while loop:
while (getline(cin, line))
However, that gives an entire line and then I cannot seem to separate the string from the integer. Suggestions would be most appreciated! :)
If the string and the integer is separated by whitespace;
Do this:
while(std::cin>>your_string>>your_num>>std::ws){}
You can choose your own delimiter, by writing a manipulator yourself.
Another approach would be to do it your way, and put the input line into a stringstream and extract the string and numbers from it. That approach seems roundabout to me as you get strings from a stream only to put it into another stream.
cin>>a
The above statement reads a token from standard input and stores it in the a variable. What is less known is that it also returns a bool value. When you reach the end of all standard input, the above statement would return false.
Use it in an if statement!
if(c>>a){
cout<<"End of standard input has been reached!";
}