This is how I am trying to get the current working directory:
char* ch;
if( (ch = _getcwd( NULL, 0 )) == NULL )
{
cout << "Could not get working directory!" << endl;
}
// skonvertujme char* na string, s tym sa nizsie bude lahsie pracovat
stringstream ss;
string workingDirectory;
ss << ch;
ss >> workingDirectory;
cout << workingDirectory << endl;
cin.get();
cin.get();
Which prints out:
C:\Users\Richard\Documents\Visual
Instead of the actual working directory:
C:\Users\Richard\Documents\Visual Studio 2010\Projects\Client\Debug
It seems like ti cuts everything after a space.
How can I get the working directory correctly even if there are spaces in the path?
The >> operator stops at the first space. Instead of the stringstream manipulation try
string workingDirectory(ch);
Just replace this:
stringstream ss;
string workingDirectory;
ss << ch;
ss >> workingDirectory;
with this:
string workingDirectory(ch);
Use getline(ss, workingDirectory)
The reason that happens is that the << operator in stringstream stops reading when it encounters whitespace.
If you really want to use your solution - which is overkill - use the noskipws io-manipulator like so:
ss >> noskipws >> workingDirectory;
Related
I am trying to read lines of a file (cityName, hiTemp, loTemp) into a struct array. I was able to use >> to read the first several lines until I hit a city with a space in it's name.
I then tried using getline() to read the lines, but then my while loop stopped working.
I have no clue why this would happen.
int LoadData()
{
int count = 0;
string path;
cout << "Specify the input file path: ";
ifstream inFile;
cin >> path;
inFile.open(path.c_str());
if (!inFile.is_open())
{
cout << "Error - could not open file: " << path;
return (-1);
}
else
{
while (!inFile.eof())
{
cities[count].city = "";
getline(inFile, cities[count].city);
if (cities[count].city.length() == 0)
{
break;
}
char comma;
inFile >> (cities[count].high) >> comma >> cities[count].low;
cout << cities[count].city << " " << cities[count].high << " " << cities[count].low << endl;
count++;
}
inFile.close();
inFile.clear(std::ios_base::goodbit);
return count;
}
}
while (!inFile.eof())
For getting every line in the file, you should use:
while(getline(inFile, cities[count].city)) {
// ...
This works and is recommended over using the .eof() method.
You can also use this in your if-statement:
if (!getline(inFile, str))
break;
As an aside, you can read this site:
Why is “while ( !feof (file) )” always wrong? - StackOverflow post
It gives insight into why using the .eof() is not the preferred method to use in a while loop to check whether the end-of-file has been reached.
Use getline as loop condition. You can also replace the second read with a getline too and use a stringstream to parse it.
#include <sstream>
// ...
while(getline(inFile, cities[count].city)) {
if (cities[count].city.empty()) break;
// read next line with high and low values
string str;
if (!getline(inFile, str)) break; // error in file format
stringstream ss(str);
char comma;
ss >> cities[count].high >> comma >> cities[count].low; // parse it
}
I'm trying to create some code to open a file, read the content and check if a couple of integers are equal by using getline(). The problem is that it seems to work only with strings, instead of doing it with integers aswell. Could you help me?
fstream ficheroEntrada;
string frase;
int dni, dnitxt;
int i=0;
int time;
cout << "Introduce tu DNI: ";
cin >> dni;
ficheroEntrada.open ("Datos.txt",ios::in);
if (ficheroEntrada.is_open()) {
while (! ficheroEntrada.eof() ) {
getline (ficheroEntrada, dnitxt);
if (dnitxt == dni){
getline (ficheroEntrada, frase);
cout << dni << " " << frase << endl;
}else{
getline (ficheroEntrada, dnitxt);
}
}
ficheroEntrada.close();
}
getline() member function is used to extract string input. So it would be better if you input data in form of string and then use "stoi" (stands for string to integer) to extract only integer values from the string data.
You can check how to use "stoi" seperately.
getline doesn't read an integer, only a string, a whole line at a time.
If I understand correctly, you are searching for the int dni into the file Datos.txt. What is the format of the file ?
Assuming it looks something like this:
4
the phrase coressponding to 4
15
the phrase coressponding to 15
...
You can use stoi to convert what you've read into an integer:
string dni_buffer;
int found_dni
if (ficheroEntrada.is_open()) {
while (! ficheroEntrada.eof() ) {
getline (ficheroEntrada, dni_buffer);
found_dni = stoi(dni_buffer);
if (found == dni){
getline (ficheroEntrada, frase);
cout << dni << " " << frase << endl;
}else{
// discard the text line with the wrong dni
// we can use frase as it will be overwritten anyways
getline (ficheroEntrada, frase);
}
}
ficheroEntrada.close();
}
This is not tested.
C++ has two type of getline.
One of them is a non-member function in std::string. This version extracts from a stream into a std::string object getline. Like:
std::string line;
std::getline( input_stream, line );
The other one is a member function of an input-stream like std::ifstream and this version extracts from the stream into an array of character getline like:
char array[ 50 ];
input_stream( array, 50 );
NOTE
Both versions extracts characters from a stream NOT a real integer type!
For having an answer to your question, you should know what type of data you have in your file. A file like this: I have only 3 $dollars!; when you try to read that, by using std::getline or input_stream.getline you cannot extract 3 as in integer type!. Instead of getline you can use operator >> to extract a single data one-by-one; like:
input_stream >> word_1 >> word_2 >> word_3 >> int_1 >> word_4;.
Now int_1 has the value: 3
Practical Example
std::ifstream input_stream( "file", std::ifstream::in );
int number_1;
int number_2;
while( input_stream >> number_1 >> number_2 ){
std::cout << number_1 << " == " << number_2 << " : " << ( number_1 == number_2 ) << '\n';
}
input_stream.close();
The output:
10 == 11 : 0
11 == 11 : 1
12 == 11 : 0
I want to know whether I'm using the right form to get my command in a line and then by some ifs get the info each command needs. This is a part of my code; actually, the first part of my main function:
string line;
stringstream ss;
while (!cin.eof())
{
getline(cin, line);
//i dont know if next line should be used
ss << line;
if (line.size() == 0)
continue;
ss >> command;
if (command == "put")
{
string your_file_ad, destin_ad;
ss >> your_file_ad >> destin_ad;
//baraye history ezafe shod
give_file(your_file_ad, p_online)->index_plus(command);
I tried to run your code with two additional couts in your if, to see what happens when for example user enters put a b.
So, this is my code:
string line;
stringstream ss;
while (true)
{
getline(cin, line);
//i dont know if next line should be used
ss << line;
if (line.size() == 0)
continue;
string command;
ss >> command;
if (command == "put")
{
string your_file_ad, destin_ad;
ss >> your_file_ad >> destin_ad;
cout << "input #1 is " << your_file_ad << endl;
cout << "input #2 is " << destin_ad << endl;
}
}
When I run this code, then if I write put a b in the console, I'll see this result, which is correct:
input #1 is a
input #2 is b
But it seems that this only works for the first command. after that commands couldn't process correctly.
So, I read the code again, and found out that the problem is, you are initializing your stringstream outside of the while.
I'm not sure why exactly it doesn't work (maybe already reached EOF and can't continue reading anymore?), but if you move stringstream ss; inside the while, it'll work correctly:
string line;
while (true)
{
stringstream ss;
getline(cin, line);
//i dont know if next line should be used
ss << line;
if (line.size() == 0)
continue;
string command;
ss >> command;
if (command == "put")
{
string your_file_ad, destin_ad;
ss >> your_file_ad >> destin_ad;
cout << "input #1 is " << your_file_ad << endl;
cout << "input #2 is " << destin_ad << endl;
}
}
Update: read #LightnessRacesinOrbit comment below about the issue with the first code.
so I was trying to utilise the istringstream to parse through a text file. The idea is to break down each line by space and based on the substring do stuff. The code works fine except for two things, it double counts last substring for each line and it seg faults when its done reading through the file. I have not used sstream before so any insight would be helpful.
file.getline(str,80);
while(!file.eof())
{
cout<<str<<endl;
istringstream iss(str);
while (iss)
{
iss >> sstr;
cout << "Substring: " <<sstr << endl;
}
file.getline(str,80);
}
The while loops should go like this:
std::string line;
while (std::getline(file, line))
{
std::istringstream iss(line);
std::string token;
while (iss >> token)
{
cout << "Substring: " << token << endl;
}
}
The getline and input operations return the stream object, which itself has a specialized conversion to bool that indicates whether the operation succeeded, and it will fail precisely when you've reached the end of the respective stream.
while !eof is almost always wrong.
Switch to a different C++ book, and tell us which one you're using now so that we may mock and warn accordingly.
while (file.getline(str,80)) {
cout<<str<<endl;
istringstream iss(str);
while (iss >> sstr) {
cout << "Substring: " <<sstr << endl;
}
}
cout << "How many questions are there going to be on this exam?" << endl;
cout << ">>";
getline(cin, totalquestions);
This small piece of code comes from a function in a class that I have created and I need totalquestions to be an int so that it can run through a for loop and keep asking the total amount of questions that I have asked.
question q;
for(int i = 0; i < totalquestions; i++)
{
q.inputdata();
questions.push_back(q);
}
Where does this piece of code comes to play? Does anyone have any idea to make this work?
Use
cin >> totalquestions;
Check the errors too
if (!(cin >> totalquestions))
{
// handle error
}
getline reads an entire line as a string. You'll still have
to convert it into an int:
std::string line;
if ( !std::getline( std::cin, line ) ) {
// Error reading number of questions...
}
std::istringstream tmp( line );
tmp >> totalquestions >> std::ws;
if ( !tmp ) {
// Error: input not an int...
} else if ( tmp.get() != EOF ) {
// Error: unexpected garbage at end of line...
}
Note that just inputting std::cin directly into
totalquestions does not work; it will leave the trailing
'\n' character in the buffer, which will desynchronize all of
the following input. It's possible to avoid this by adding a
call to std::cin.ignore, but this would still miss the error
due to trailing garbage. If you're doing line oriented input,
stick with getline, and use std::istringstream for any
necessary conversions.
Do this:
int totalquestions;
cout << "How many questions are there going to be on this exam?" << endl;
cout << ">>";
cin >> totalquestions;
Getline is meant for grabbing chars. It can be done with getline(), but cin is much easier.
One of the better ways of getting an int from user :-
#include<iostream>
#include<sstream>
int main(){
std::stringstream ss;
ss.clear();
ss.str("");
std::string input = "";
int n;
while (true){
if (!getline(cin, input))
return -1;
ss.str(input);
if (ss >> n)
break;
std::cout << "Invalid number, please try again" << std::endl;
ss.clear();
ss.str("");
input.clear();
}
Why is it better than using cin >> n ?
Actual article explaining why
As for your question, use the above code to get the int value and then use it in the loop.
Don't use getline:
int totalquestions;
cin >> totalquestions;