Checking for incoming data type from file - c++

I'm reading in from a .txt file that looks something along the lines of:
int string string string
int string string
int string string string string string
where the number of string types after each int is unknown. Each line represents a new group of values and each group needs to be into their own array value or whatever (don't know if I've worded that correctly but I hope you'll understand what I mean).
Is there a check I can perform so see if the incoming data from the file is an int so that if this is true and can tell my program its a new group of data?
I've tried
int check
if(check = file1.peek()){//start new group assignment}
but this doesn't appear to work. I need to be able to use the int value once I have found that it is the next data type being read in.
Thanks in advance.

There are several ways to do this, however I would suggest that maybe your groups are on separate lines, and the spaces within a line delimit items within a group correct?
So I would read the file, line-at-a-time and then split each line on spaces.
Let me know if the above fits and then we can explain how to do it.
Ok so you can use getline:
while (cin.good()) // reading from standard input until EOF
{
String line_str;
getline(cin, line_str); // get next line from standard input
istringstream line(line_str); // put line into string stream
if (line.good()) // read from string stream until EOF
{
int x;
line >> x; // read an integer from string stream
while (line.good()) // read from string stream until EOF
{
string s;
line >> s; // read strings from string stream
/// process s
}
}
}

Related

How can we take out the multiple integer numbers in the string array or string and assign them to different int data type?

I am new to C++ and I am reading in a text file. The content of text file is like:
$ (first line)
2 (second)
MY NAME IS (whatever sentence with 10 or below characters)(third)
12 21 (forth)
22 22 (fifth)
221 (sixth)
fly jump run (seventh)
fish animal (eighth)
So I need to read all of these and store them into different variables line by line and so far I'd manage to store them into string array line by line but how can I store the numbers like 12 21 in forth line into 2 different integer variables such as int b and int c?
and also like last two line
how can I store the fly jump run fish animal into 5 different string variables respectively?
Basically Now I am putting them into a string array line by line and trying to access them and take them out of the array and store it.
if (file.is_open()){
cout<<"Congratulations! Your file was successfully read!";
while (!file.eof()){
getline(file,line);
txt[i]=line;
i++;
}
}
Just want to store every line into variables based on their data type.
The streams support streaming the content directly into the basic data types (int, double etc.). So the istream::operator>>(int&) does the work for you.
The below small sample class demonstrates it by reading your sample file into the members -- hope that helps:
class Creature
{
public:
void read(istream& stream)
{
string line;
stream.ignore(10, '\n'); // skip line 1 (= $)
stream >> m_integers[0]; // line 2 = single int
stream.ignore(1, '\n'); // skip end of line
getline(stream, m_sentence); // get the full sentence line ..
// and the rest ... we can read that in a single code line ...
stream >> m_integers[1] >> m_integers[2] >> m_integers[3] >> m_integers[4]
>> m_integers[5] >> m_whatCanIdDo[0] >> m_whatCanIdDo[1] >> m_whatCanIdDo[2] >> m_whatIAm[0] >> m_whatIAm[1];
}
private:
string m_sentence;
int m_integers[6];
string m_whatCanIdDo[3];
string m_whatIAm[2];
};
Calling the function:
int main()
{
ifstream file;
file.open("creature.txt");
Creature cr;
cr.read(file);
file.close();
}
There are several ways of doing this, but one of the most straightforward is to use a stringstream.
To do this, copy the lines you want to tokenize from your txt array into a stringstream. Use the stream extratction operator (>>) to read out each word from that line, separated by a space, into a separate variable.
//Required headers
#include <string>
#include <sstream>
...
string word1, word2;
stringstream words(txt[lineNumber]);
words >> word1 >> word2;
//Process words
For each line you tokenize, you'll have to reset the stream.
//Read in next line
lineNumber++;
//Reset stream flags
words.clear();
//Replace the stream's input string
words.str(txt[lineNumber]);
words >> word1 >> word2;
//Process new words
You can use the same process for both integers and strings. The stream extraction operator will automatically convert strings to whatever data type you give it. However, it's up to you to make sure that the data it's trying to convert is the correct type. If you try to write a string to an int using a stringstream, the stringstream will set a fail bit and you won't get any useful output.
It's a good idea to write your input to a string, and then check whether that string is, in fact, a number, before trying to write it to an integer. But that's an entirely different topic, there are many ways to do it, and there are several other questions on this site that cover it.

File input and process data

I would like to read from a text file and the format of the file is
Method 1
Method 2
Insert 3 "James Tan"
I am currently using ifstream to open the text file and read the items, but when I use >> to read the lines, which is causing the name not to be fully read as "James Tan".
Attached below is the code and the output.
ifstream fileInput;
if(fileInput.is_open()){
while(fileInput.good()){
fileInput >>methondName>>value>>Name;
......
Output
methodName = Method, Method, Insert
value = 1, 2, 3 (must be a usigned integer)
Name = James
What is the better way to process the reading of the lines and the contents.
I was told about getline. But i understand that getline reads fully as a line rather than a single word by single word.
Next is fstream really fast?. cause, I would like to process 500000 lines of data and if ifstream is not fast, what other options do I have.
Please advice on this.
Method 1
Method 2
Insert 3 "James Tan"
I take it you mean that the file consists of several lines. Each line either begins with the word "Method" or the word "Insert", in each case followed by a number. Additionally, lines that begin "Insert" have a multi-word name at the end.
Is that right? If so, try:
ifstream fileInput("input.txt");
std::string methodName;
int value;
while ( fileInput >> methodName >> value ) {
std::string name;
if(methodName == "Insert")
std::getline(fileInput, name);
// Now do whatever you meant to do with the record.
records.push_back(RecordType(methodName, value, name); // for example
}

Reading a text file in c++

string numbers;
string fileName = "text.txt";
ifstream inputFile;
inputFile.open(fileName.c_str(),ios_base::in);
inputFile >> numbers;
inputFile.close();
cout << numbers;
And my text.txt file is:
1 2 3 4 5
basically a set of integers separated by tabs.
The problem is the program only reads the first integer in the text.txt file and ignores the rest for some reason. If I remove the tabs between the integers it works fine, but with tabs between them, it won't work. What causes this? As far as I know it should ignore any white space characters or am I mistaken? If so is there a better way to get each of these numbers from the text file?
When reading formatted strings the input operator starts with ignoring leading whitespace. Then it reads non-whitespace characters up to the first space and stops. The non-whitespace characters get stored in the std::string. If there are only whitespace characters before the stream reaches end of file (or some error for that matter), reading fails. Thus, your program reads one "word" (in this case a number) and stops reading.
Unfortunately, you only said what you are doing and what the problems are with your approach (where you problem description failed to cover the case where reading the input fails in the first place). Here are a few things you might want to try:
If you want to read multiple words, you can do so, e.g., by reading all words:
std::vector<std::string> words;
std::copy(std::istream_iterator<std::string>(inputFile),
std::istream_iterator<std::string>(),
std::back_inserter(words));
This will read all words from inputFile and store them as a sequence of std::strings in the vector words. Since you file contains numbers you might want to replace std::string by int to read numbers in a readily accessible form.
If you want to read a line rather than a word you can use std::getline() instead:
if (std::getline(inputFile, line)) { ... }
If you want to read multiple lines, you'd put this operation into a loop: There is, unfortunately, no read-made approach to read a sequence of lines as there is for words.
If you want to read the entire file, not just the first line, into a file, you can also use std::getline() but you'd need to know about one character value which doesn't occur in your file, e.g., the null value:
if (std::getline(inputFile, text, char()) { ... }
This approach considers a "line" a sequence of characters up to a null character. You can use any other character value as well. If you can't be sure about the character values, you can read an entire file using std::string's constructor taking iterators:
std::string text((std::istreambuf_iterator<char>(inputFile)),
std::istreambuf_iterator<char>());
Note, that the extra pair of parenthesis around the first parameter is, unfortunately, necessary (if you are using C++ 2011 you can avoid them by using braces, instead of parenthesis).
Use getline to do the reading.
string numbers;
if (inputFile.is_open())//checking if open
{
getline (inputFile,numbers); //fetches entire line into string numbers
inputFile.close();
}
Your program does behave exactly as in your description : inputFile >> numbers; just extract the first integer in the input file, so if you suppress the tab, inputFile>> will extract the number 12345, not 5 five numbers [1,2,3,4,5].
a better method :
vector< int > numbers;
string fileName = "text.txt";
ifstream inputFile;
inputFile.open(fileName.c_str(),ios_base::in);
char c;
while (inputFile.good()) // loop while extraction from file is possible
{
c = inputFile.get(); // get character from file
if ( inputFile.good() and c!= '\t' and c!=' ' ) // not sure of tab and space encoding in C++
{
numbers.push_back( (int) c);
}
}
inputFile.close();

Read portions of an ifstream into a string object?

I'm trying to read an ifstream into a string, where I can set the number of characters being read. I've read the documentation for ifstream.get() and ifstream.getline(), but neither of those accomplish what I want.
Given the following string:
asdfghjklqwertyuiop
I want to read in varying number of characters at a time into a string. I've started like this, but I'm getting an error that there's no function that will take a string as the first parameter:
string destination;
int numberOfLettersToGet = 1;
while (inputstream.get(destination, numberOfLettersToGet)){
//Do something.
}
What can I use instead of inputstream.get()?
You may like to use read and gcount member-functions of std::istream. get appends a zero-terminator, which is unnecessary when you read into std::string.
std::string destination;
int numberOfLettersToGet = 1;
destination.resize(numberOfLettersToGet);
std::streamsize n = inputstream.gcount();
inputstream.read(&destination[0], numberOfLettersToGet);
destination.resize(inputstream.gcount() - n); // handle partial read
istream::get returns the character as an integer, so you simply need to append the returned character as the next character of the string. e.g.
while (string.push_back(inputstream.get()))
{ //...
}

Read blank line C++

I am in a situation where i had a loop and everytime it reads a string but I dont know how to read blank input i.e if user enter nothing and hit enter, it remains there.
I want to read that as string and move to next input
below is the code
int times = 4;
while(times--)
{
string str;
cin>>str;
---then some other code to play with the string---
}
You would need to read the entire line using getline(). Then you would need to tokenize the strings read.
Here is a reference on using getline and tokenizing using stringstream.
char blankline[100];
int times = 4;
while(times--)
{
//read a blank line
cin.getline(blankline,100);
---then some other code to play with the string---
}