How to separate data from getline each time there is a space - c++

int main() {
ifstream billFile;
billFile.open("bill.in"); //opening file
if( billFile.is_open() ){
string line1;
getline(billFile, line1);
cout << line1 << endl;
}
The bill.in file contains:
12 100
How can I separate 12 and 100 into two different variables?

You can use std::istringstream to parse line1:
int main()
{
ifstream billFile("bill.in"); //opening file
if( billFile.is_open() )
{
string line1;
if( getline(billFile, line1) )
{
istringstream iss(line1);
int value1, value2;
if( iss >> value1 >> value2 )
cout << value1 << ' ' << value2 << endl;
}
}
}
Of course, if your file has only 1 line, then you can just omit getline(), eg:
int main()
{
ifstream billFile("bill.in"); //opening file
if( billFile.is_open() )
{
int value1, value2;
if( billFile >> value1 >> value2 )
cout << value1 << ' ' << value2 << endl;
}
}

I use the following split function to divvy up each line based on some set of delimiters (a space in your case).
std::vector<std::string> split(const std::string& str,
std::string delims = " \t") {
std::vector<std::string> strings;
size_t start;
size_t end = 0;
while ((start = str.find_first_not_of(delims, end)) != std::string::npos) {
end = str.find_first_of(delims, start);
strings.push_back(str.substr(start, end - start));
}
return strings;
}
then you can split each line into a vector of strings:
int main() {
ifstream billFile;
billFile.open("bill.in"); //opening file
if( billFile.is_open() ){
string line;
getline(billFile, line);
std::vector<std::string> str = split(line, " ");
std::string line1 = str[0];
cout << line1 << endl;
}
}
You use this method to split up strings using any delimiter you want.

If you input file only contains one line and your keyboard is in very poor working order and you really need to minimize keystrokes you can write:
int main(){
int v1, v2;
if(std::ifstream("bill.in") >> v1 >> v2){
// here you have valid v1 and v2.
}
}
The >> "formatted input" is appropriate here because it is convenient to understand the contents of the text file as numbers.

Function std::getline() takes delimitation as claimed in C++ reference. So just use getline(istream, str, ' ');.
Modify your codes as
int main() {
ifstream billFile;
billFile.open("bill.in"); //opening file
if( billFile.is_open() ){
string line1;
getline(billFile, line1, ' ');
cout << line1 << endl;
}

Related

How to read integer values separated by different delimiters on each line in a file?

I have a text file containing integer values separated on each line by a different character.
So the user enters the file name then a function that takes a file name is called and return the sum of all the integer values read.
On each line the user is prompted to input the separator.
If the file opening failed the function getSum() should report that through an error output stream object and returns -1.
Here is what I've tried:
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
int getSum(std::string const& fileName){
std::ifstream in(fileName);
if(!in){
std::cerr << "Unable to open input file!\n";
return -1;
}
int sum = 0;
for(std::string line; std::getline(in, line); ){
std::cout << "enter separator: ";
char separator;
std::cin.get(separator);
std::istringstream iss(line);
for(std::string strVal; std::getline(iss, strVal, separator); ){
sum += std::stoi(strVal);
}
}
return sum;
}
int main(){
std::string fileName;
std::cout << "File name: ";
std::getline(std::cin, fileName);
std::cout << getSum(fileName) << '\n';
std::cout << '\n';
}
The input file: data.txt:
25 20 16
7 0 3
Separator: ' '
The output:
68
Why it is not 71 as guessed?
And if I make char separator= ' '; and remove std::cin.get(separator); it gives me the correct output: 71. So I guess the problem is with std::cin.get(separator).
So is there a workaround?
Here is the problem:
int getSum(std::string const& fileName){
std::ifstream in(fileName);
if(!in){
std::cerr << "Unable to open input file!\n";
return -1;
}
int sum = 0;
for(std::string line; std::getline(in, line); ){
std::cout << "enter separator: ";
char separator;
std::cin.get(separator); //every time the for-loop loops, this happens again, resetting separator
std::istringstream iss(line);
for(std::string strVal; std::getline(iss, strVal, separator); ){
sum += std::stoi(strVal);
}
}
return sum;
}
Here is the fix:
int getSum(std::string const& fileName) {
std::ifstream in(fileName);
if (!in) {
std::cerr << "Unable to open input file!\n";
return -1;
}
int sum = 0;
std::cout << "enter separator: ";
char separator;
separator = std::cin.get(); //get separator BEFORE the for-loop
for (std::string line; std::getline(in, line); ) {
std::istringstream iss(line);
for (std::string strVal; std::getline(iss, strVal, separator); ) {
sum += std::stoi(strVal);
}
}
return sum;
}
It now outputted 71 as expected.

How to skip blank lines when reading a file in c++?

Ok, so here is the text of the file I am trying to read:
KEYS
a set of keys
3
LAMP
a brightly shining brass lamp
8
ROD
a black rod with a rusty star
12
Ok, so pretend that each line is evenly spaced, but there are 2 blank lines, (or tabs) between 8 and ROD. How would I skip that and continue with the program? I am trying to put each line into 3 vectors (so keys, lamp, and rod into one vector etc). Here is my code (but it does not skip the blank line).:
#include <string>
#include <iostream>
#include <sstream>
#include <vector>
#include <fstream>
using namespace std;
int main() {
ifstream objFile;
string inputName;
string outputName;
string header;
cout << "Enter image file name: ";
cin >> inputName;
objFile.open(inputName);
string name;
vector<string> name2;
string description;
vector<string> description2;
string initialLocation;
vector<string> initialLocation2;
string line;
if(objFile) {
while(!objFile.eof()){
getline(objFile, line);
name = line;
name2.push_back(name);
getline(objFile, line);
description = line;
description2.push_back(description);
getline(objFile, line);
initialLocation = line;
initialLocation2.push_back(initialLocation);
} else {
cout << "not working" << endl;
}
for (std::vector<string>::const_iterator i = name2.begin(); i != name2.end(); ++i)
std::cout << *i << ' ';
for (std::vector<string>::const_iterator i = description2.begin(); i != description2.end(); ++i)
std::cout << *i << ' ';
for (std::vector<string>::const_iterator i = initialLocation2.begin(); i != initialLocation2.end(); ++i)
std::cout << *i << ' ';
I think you can check to see if the string is empty thru std::getline. If it is, then you can ignore it or something like.
getline(objFile, line);
name = line;
while(name.length() == 0)
{
getline(objFile, line);
name = line;
}
name = line;
name2.push_back(name);
getline(objFile, line);
description= line;
while(description.length() == 0)
{
getline(objFile, line);
description = line;
}
description= line;
description2.push_back(description);
getline(objFile, line);
initialLocation = line;
while(initialLocation.length() == 0)
{
getline(objFile, line);
initialLocation = line;
}
initialLocation = line;
initialLocation2.push_back(initialLocation );
If i am correct then a line will have no length if it is blank and if it is we check again therefore ignoring it.
You can use std::getline() (As pointed out by many people) instead... which will yield each line one-by-one:
inline std::string ReadFile(std::ifstream& stream)
{
std::string contents;
std::string temporary;
while (std::getline(stream, temporary))
if (!std::all_of(temporary.begin(), temporary.end(), isspace))
contents.append(temporary + "\n");
return contents.substr(0, contents.size() - 1);
}
And yes, an example:
int main()
{
std::ifstream is("file.txt");
if (is.fail())
return 1;
auto const contents = ReadFile(is);
is.close();
std::cout << contents << std::endl;
std::cin.get();
return 0;
}

How do separate a string from a text file

I have a text file that has information format like this:
id last,first string
for example:
0 Snow,John nothing
1 Norris,Chuck everything
How do i get last name and first name stored separately?
To get information from file, I did:
#include <fstream>
int id;
string str;
string last;
string first;
int main()
{
ifstream myfile(ex.txt);
myfile >> id;
while (myfile)
{
for (int i = 0; i < 4; i++) // this is the amount of times i'll get information from 1 line
{
id = id; // its actually some_structure.id = id, omit
getline(myfile, last, ','); // i think i need to use another function as getline get the whole line
cout << id;
cout << last; // print out the whole line!
}
}
}
ifstream myfile;
string line;
while (getline(myfile, line))
{
istringstream ss(line);
int id;
ss >> id;
string fullname;
ss >> fullname;
string firstname, lastname;
{
istringstream ss2(fullname);
getline(ss2, lastname, ',');
getline(ss2, firstname);
}
}
if (std::ifstream input(filename))
{
int id;
string lastname, firstname, other_string;
while (input >> id && getline(input, lastname, ',') &&
input >> firstname >> other_string)
... do whatever you like...
if (!input.eof())
std::cerr << "error while parsing input\n";
}
else
std::cerr << "error while opening " << filename << '\n';
The code above has more error checking than the other answers I've seen, but admittedly - because it doesn't read text a line at a time then parse out the fields, it would happily accept e.g.:
10 Chuck,
Norris whatever
Would recomend something like this:
string name;
myfile >> id >> name >> str;
first = name.substr(0, name.find(","));
last = name.substr(name.find(",") + 1);
Note that your EOF checking is incorrect.
// The complete code that will do the job
// Please remove uncomment all code
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main () {
string line;
ifstream myfile ("ex.txt");
if (myfile.is_open())
{
while ( getline (myfile,line) )
{
cout << line << '\n';
string last = line.substr(line.find(" ") + 1, line.find(",") - 2);
string first = line.substr(line.find(",") + 1, line.find(",") + line.find(" ") - 1);
}
myfile.close();
}
else {
cout << "Unable to open file";
}
return 0;
}

Trouble with reading/outputting files

I want to open a file for reading then output what is in that .txt file, any suggestion on my code?
string process_word(ifstream &word){
string line, empty_str = "";
while (!word.eof()){
getline(word, line);
empty_str += line;
}
return empty_str;
}
int main(){
string scrambled_msg = "", input, output, line, word, line1, cnt;
cout << "input file: ";
cin >> input;
ifstream inFile(input);
cout << process_word(inFile);
}
Instead of:
while (!word.eof()) {
getline(word, line);
empty_str += line;
}
do:
while ( std::getline(word, line) ) {
empty_str += line;
}
and it would be also wise to give your variables more appropriate names.
Your function can be simplified to:
#include <iterator>
std::string process_word(std::ifstream& word)
{
return std::string{std::istream_iterator<char>{word},
std::istream_iterator<char>{}};
}
int main()
{
string input;
std::cin >> input;
std::ifstream inFile(input);
std::cout << process_word(inFile);
}

C++: File I/O having difficulty with opening and working with it

I'm having difficulty opening files and processing what is inside of them. What i want to do is
pull a line from the input file
init an istreamstream with the line
pull each word from the istringstream
i. process the word
do my specific function i've created
ii. write it to the output file
I'm not sure how to go about doing 1-3 can anyone help with my functions? This is what i have so far...
string process_word(ifstream &inFile){
string line, empty_str = "";
while (getline(inFile,line)){
empty_str += line;
}
return empty_str;
}
int main(){
string scrambled_msg = "", input, output, line, word, line1, cnt;
cout << "input file: ";
cin >> input;
cout << "output file: ";
cin >> output;
ifstream inFile(input);
ofstream outFile(output);
cout << process_word(inFile);
}
std::vector<std::string> process_word(std::ifstream& in)
{
std::string line;
std::vector<std::string> words;
while (std::getline(in, line)) // 1
{
std::istringstream iss{line}; // 2
std::move(std::istream_iterator<std::string>{in},
std::istream_iterator<std::string>{},
std::back_inserter(words));
}
return words;
}
int main()
{
std::ifstream in(file);
std::ofstream out(file);
auto words = process_word(in);
for (auto word : words)
// 3 i.
std::move(words.begin(), words.end(), // 3 ii.
std::ostream_iterator<std::string>{out});
}