I want to read string in a file using c++.
The input string like: "File: blacksburg.asc"
I need to read string after ":"
Part of my code as following:
void mapWalk( string input, string output ){
ifstream in(input.c_str());
string line;
string mapdata = "";
getline(in,line);
int pos = line.find(":");
mapdata = line.substr(pos);
cout<<"The string is"<< mapdata <<"&&" << endl;
}
The output is shown as following:
&&e string is: blacksburg.asc
It is so wired!!
Why && is at begin of the string and cover the other?
Does someone have ideas?
There's a carriage return character at the end of mapdata. So you output "The string is", then the contents of mapdata including the carriage return. Then you output && on top of the previous text because you returned the carriage without a line feed.
Read the documentation for getline. It specifies that the line ending is not removed.
Related
I want to read and extract the actors Surname from opened text file.
I tried to do it like this, but It could only read every other word from the sentences.
The Actors surname ends with a semicolon but I don`t know how to proceed.
(I don't want to use vectors as I don't fully understand them)
bool check=false;
while (!check) //while false
{
string ActorSurname = PromptString("Please enter the surname of the actor:");
while (getline (SecondFile,line)) //got the line. in a loop so keeps doing it
{
istringstream SeperatedWords(line); //seperate word from white spaces
string WhiteSpacesDontExist;
string lastname;
while (SeperatedWords >> WhiteSpacesDontExist >> lastname) //read every word in the line //Should be only second word of every line
{
//cout<<lastname<<endl;
ToLower(WhiteSpacesDontExist);
if (lastname == ActorSurname.c_str())
{
check = true;
}
}
}
}
Assuming that each line of your file contain two words separated with space (and second word ends with semicolon), below is example how you can read second word from such string:
#include <string>
#include <iostream>
int main()
{
std::string text = "John Smith;"; // In your case, 'text' will contain your getline() result
int beginPos = text.find(' ', 0) + 1; // +1 because we don't want to read space character
std::string secondWord;
if(beginPos) secondWord = text.substr(beginPos, text.size() - beginPos - 1); // -1 because we don't want to read semicolon
std::cout << secondWord;
}
Output:
Smith
In this example, we use method find of std::string class. This method returns position of character we look for (or -1 if character wasn't found), which we can use to determine begin index required in substr method.
I'm trying to write a program that can open a text file, find a certain string and substitute it with another string and then write the altered text to an output file.
This is what I've coded so far. It works fine, except for that the output file is missing spaces and new line characters.
I need to preserve all spaces and new line characters. How do I do it?
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string search = "HELLO"; //String to find
string replace = "GOODBYE"; //String that will replace the string we find
string filename = ""; //User-provided filename of the input file
string temp; //temp variable for our loop to hold the characters from the file stream
char c;
cout << "Input filename? ";
cin >> filename;
ifstream filein(filename); //File to read from
ofstream fileout("temp.txt"); //Temporary file
if (!fileout || !filein) //if either file is not available
{
cout << "Error opening " << filename << endl;
return 1;
}
while (filein >> temp) //While the stream continues
{
if (temp == search) //Check if the temp variable has captured the string we are looking for
{
temp = replace; //When we found the string, we substitute it with the replacement string
}
fileout << temp; //Dump everything to fileout (our temp.txt file)
}
//Close our file streams
filein.close();
fileout.close();
return 0;
}
UPDATE:
I followed your advice and did the following, but now it doesn't work at all (the previous code worked fine, except for white spaces). Could you kindly tell me what I'm doing wrong here?
Thank you.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
string search = "or"; //String to find
string replace = "OROROR"; //String that will replace the string we find
string filename = ""; //User-provided filename of the input file
string temp = ""; //temp variable for our loop to hold the characters from the file stream
char buffer;
cout << "Input filename? ";
cin >> filename;
ifstream filein(filename); //File to read from
ofstream fileout("temp.txt"); //Temporary file
if (!fileout || !filein) //if either file is not available
{
cout << "Error opening " << filename << endl;
return 1;
}
while (filein.get(buffer)) //While the stream continues
{
if (buffer == ' ') //check if space
{
if (temp == search) //if matches pattern,
{
temp = replace; //replace with replace string
}
}
temp = string() + buffer;
for (int i = 0; temp.c_str()[i] != '\0'; i++)
{
fileout.put(temp.c_str()[i]);
}
return 0;
}
}
while (filein >> temp)
This temp variable is a std::string. The formatted extraction operator, >>, overload for a std::string skips all whitespace characters (spaces, tabs, newlines) in the input and completely discards them. This formatted extraction operator discards all whitespace until the first non-whitespace character, then extracts it and all following non-whitespace characters and places them into your std::string, which is this temp variable. This is how it works.
Subsequently:
fileout << temp;
This then writes out this string to the output. There's nothing in the shown code that tells your computer to copy all whitespace from the input to the output, as is. The only thing that the shown code does is extract every sequence of non-space characters from the input file, immediately throwing on the floor all spaces and newlines, never to be seen again; and then write what's left (with the appropriate changes) to the output file. And a computer will always do exactly what you tell it to do, and not what you want it to do.
while (filein >> temp)
This is where all spaces in the input file gets thrown in the trash, and discarded. Therefore you wish to preserve them and copy them to the output file, as is, you will have to replace this.
There are several approaches that can be used here. The simplest solution is to simply read the input file one character at a time. If it's not a whitespace character, add it to the temp buffer. If it's a whitespace character, and temp is not empty, then you've just read a complete word; check if it needs replacing; write it out to the output file; clear the temp buffer (in preparation for reading the next word); and then manually write the just-read whitespace character to the output file. In this manner you will copy the input to the output, one character at a time, including spaces, but buffering non-space character into the temp buffer, until each complete word gets read, before copying it to the output file. And you will also need to handle the edge case of handling the very last word in the file, without any trailing whitespace.
The issue is I've this file but I don't how obtain the string or numbers on it without quotes or commas ,and put it in auxiliar variable,
"string one" , 2500:25670, (0.676,-2.43)
"string two",259: 8765 , ( 12.22 , -7.56 )
For the moment I wrote this code:
string filename = getFilename(); //function to get filename
string line;
string data;
ifstream file;
file.open(filename.c_str(),ios::in);
if (!file.is_open())
{
error(ERR_CANT_OPEN_FILE);
}
else
{
while(getline(file,line))
{
bases.push_back(tempBases));
}
}
In the loop of reading file line by line:
while(getline(file,line))
{
// parse line to a token of strings with comma delimiter and assign each token to variables or put to the vector
}
I'm struggling to find a way to both read a file to the end of a line, such as
dog \n
cat \n
pig
and store the char of each to an array. While I can do this for one line, I can't work out how to move on to the next line (ie dog to cat) and still register the end of the file.
Here is my code so far;
searchFile.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
char next;
while (searchFile.get(next))
{
if (next == '\n') // If the file has been opened in
{
for (int i = 0; i <= searchTempSize; i++) // ... For each character within the total length of the string ...
{
searchCharArray[i] = searchArray[i];
cout << searchCharArray[i] << endl;
}
}
}
Edit for clarity: I need to read the file and store the characters of each word as an array. However, the file contains each word on a new line. I can't seem to find a way to read on to the next line, rather than end.
The conventional way to do this is with std::getline. This returns a reference to the stream; when casted to a boolean, this indicates whether the last operation on the stream was successful, e.g., non–end-of-file. So to load all lines into an array of strings, for example, you might do the following:
std::string line;
std::vector<string> lines;
while (std::getline(searchFile, line)) {
lines.push_back(line);
}
For example, when parsing a text file, some times this file have stuff like this:
keyword a string here
keyword another string
keyword
keyword again a string
Note that the 3th line have an empty string (nothing or white spaces).. The thing is that when you do stringstream>>laststring, and stringstream have an empty string (null or just white space), it will not overwrite the "laststring", it will do nothing. Theres anyway to check this situation before hand? I dont want to create a temp empty string just to check it is still empty after stringstream>>, seems lame.
When you cannot read from stream - its state changes, so when casting to bool, it returns false:
bool read = static_cast<bool>(ss >> laststring);
Or - in if-expr:
if (ss >> laststring)
cout << "Just read: " << laststring;
See example
You can only know after trying to read whether there was something or not. What you might be able to do is to skip whitespace and see if there is a non-space in the next location:
if ((in >> std::ws).peek() != std::char_traits<char>::eof()) {
...
}
Given that empty strings are cheap to create, I wouldn't bother and try read the string. Note, however, that reading from streams isn't line based, i.e., in your case above you need to split the lines first or use something like std::getline() to read the second part of line.
You can use getline, to read a line from the file. Then, copy the line into a string stream and read words from the string stream one at a time. The streams will automatically stop reading when they run out of lines / words.
// open file
std::ifstream fin("text.txt");
// 'iterate' through all the lines in the file
unsigned lineCount = 1;
std::string line;
while (std::getline(fin, line))
{
// print the line number for debugging
std::cout << "Line " << lineCount << '\n';
// copy line into another stream
std::stringstream lineStream(line);
// 'iterate' through all the words in the line
unsigned wordCount = 1;
std::string word;
while (lineStream >> word)
{
// print the words for debugging
std::cout << '\t' << wordCount++ << ' ' << word << '\n';
}
}
You need to include iostream, fstream, sstream and string.
For checking if string is empty, use foo.size() == 0.
For checking if string stream is empty fooStream.rdbuf()->in_avail() == 0