Extract Information from colon seperated .txt file, C++ - c++

guys. I'm writing this small test program to read the text file from "EXAMPLE.txt" into my main program. At the output, I put "*" to displayed the data during the output is the data that I want to extract it out and locate into an array. Let say, in this test program the data that I wanted to extract is "JY9757AC", "AZ9107AC","GY9Z970C". But after that, I have did a try run and I faced this problem when comes to the output.
EXAMPLE.txt
ABC:JY9757AC
HDMI:AZ9107AC
SNOC:GY9Z970C
MAIN.CPP
main()
{
string output;
ifstream readExample;
readExample.open("EXAMPLE.txt");
while(readExample.eof())
{
getline(readExample,output,':');
cout << "* " << output <<endl;
}
}
OUTPUT
* ABC //while loop output the "ABC", which is the data that I don't want.
* JY9757AC
HDMI //it work's well, as what I expected and so and the SNOC below
* AZ9107AC
SNOC
* GY9Z970C
I have no any idea why is the "* ABC" is shown on the output, is there anything wrong with my logic. or I missed out something inside the while loop? Thank You in advance for helping to solve my code!

The delim parameter for getline replaces the default delimiter for new line which is "\n".
What you are currently getting as a "line" is:
ABC
JY9757AC\nHDMI
AZ9107AC\nSNOC
GY9Z970C
What you can do is more something like this (if your output like GY9Z970C) is fixed-size:
ssize_t len = getline(readExample,output,':');
cout << "* " << (char*)(output + (len - 8)) <<endl;

Output stores the first extraction from Example.txt and prints it followed by *. In the first iteration output = "ABC"; in the second iteration output = "JY9757AC";. I have added a getline() in the while loop that reads the unwanted part of the line. I also added a string[] to store the extracted values in.
#include <fstream>
#include <string>
using namespace std;
int main()
{
string output, notWanted, stringArray[3];
int i = 0;
ifstream readExample;
readExample.open("EXAMPLE.txt");
while (!readExample.eof())
{
getline(readExample, notWanted, ':');
getline(readExample, output);
cout << "* " << output << endl;
stringArray[i++] = output;
}
cin.get();
return 0;
}

First, I assume the while loop is while(!readExample.eof()), otherwise there should be no output at all.
Second, to your question, the first getline(readExample,output,':'); read "ABC" into the output, so at the next line it outputs * ABC, which is exactly what you got. No surprise.

Related

How to take multiple line string input in C++?

I am learning C++. I want to take multiple line string as input but I can't. I am using getline() for it but it is taking only one line input. When I press enter for writing next line it stoped taking input and print the first line.
I want to give input like the example below
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
But it takes only the first line input.
My code:
#include <iostream>
#include <string>
using namespace std;
int main()
{
string s;
getline(cin, s);
cout << s << endl;
return 0;
}
Please help me to know how can I do that.
Thank you.
Either you write a loop to read individual lines and concatenate them to a single string, thats what this answer suggests. If you are fine with designating a specific character to signal the end of the input, you can use the getline overload that takes a delimiter as parameter:
#include <iostream>
#include <string>
int main() {
std::string s;
std::getline(std::cin,s,'x');
std::cout << s;
}
The user would have to type an x to end input, so this input
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
x
would result in this output:
Hello, I am Satyajit Roy.
I want to make a program.
I love to travel.
Of course this won't work when the string to be entered contains x, which renders the approach rather useless.
However, instead of using a "real" character as delimiter you can use the EOF character (EOF = end of file) like this:
std::getline(std::cin, s, static_cast<char>(EOF));
Then input is terminated by whatever your terminal interprets as EOF, eg Ctrl-d in linux.
Thanks to #darcamo for enlightening me on the EOF part.
You can only read one line at a time with std::getline if you don’t provide your own delimiter. If you want to accumulate multiple lines, one at a time, you need a place to put the result. Define a second string. Read a line at a time into s with std::getline, and then append s to the result string. Like this:
std::string result;
std::string s;
while (std::getline(std::cin, s))
result += s;
You can take several lines using the code below if you know how many lines you will input.
int line=3, t;
string s, bigString;
for(int i=0 ; i<line ; i++)
{
getline(cin,s); // This is to input the sentence
bigString += s + "\n";
}
cout << bigString;
If you don't know how many lines you will input (Input from file until end of file) then you can check this.
string s;
vector<string> all;
while(getline(cin,s))
{
all.push_back(s);// This is to input the sentence
}
for(auto i:all)
{
cout << i << endl;
}

Read a line of input including space-delimited strings and display them as a single complete line using getline

I'm trying to make a simple program(hello.cpp) that takes user input in the form of a test file using getline and prints it back out on the screen.
The code looks like this:
#include <iostream>
#include <string>
using namespace std;
int main(int argc, char ** argv) {
string name;
cout << "What is your name?" << endl;
getline(cin, name);
cout << "Hello " << name << "!" << endl;
return 0;
}
The test file(test.txt) I'm using looks like this:
|
|
|John
|Doe
|
Ignore the vertical lines, I just put them there to represent the line breaks
I'm trying to get getline to ignore tabs and line breaks and just read what is in the text file as just one string.
The output I want looks like this:
$./hello < test.txt
What is your name?
Hello John Doe!
What I'm getting looks like this:
$./hello < test.txt
What is your name?
Hello !
While I don't agree with the approach you are taking here, here is how I would solve your current problem:
Since the name in test.txt is split across multiple lines, you have to keep using getline until there is no more input. Thus, you should use the following instead of a single getline statement:
string input;
while (getline(cin, input))
{
name += input;
}
This reads through every single line in the file, and adds it to the name, while ignoring whitespace (There is none anyway) and line breaks (Which signify the end of a line).
Output:
$./hello < test.txt
What is your name?
Hello JohnDoe!
Adding a space between the first and last name should be trivial, but I am going off the fact that you said whitespace should be ignored.

How to print output in a file after a few empty lines

What I want to do here, is print the word "hello", first at the beginning, then skip some lines, then print it again in the file. The number of lines I need to skip is specified by the user. The file may or may not be empty, and if it's not empty, I don't want to change data on lines other than I need to print. If the file is empty, then it has to skip empty lines and still print after some lines.
Here is my code:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main(){
ifstream f1("temp.txt");
ofstream f2("temp.txt");
int r;
cout << "Enter number of lines to skip:" ;
cin >> r;
f2 << "hello";
string org = "";
while(--r){
getline(f1, org);
cout << "org: "<< endl;
}
int pos = f1.tellg();
cout << "pos: " << pos << endl;
f2.seekp(pos, f2.beg);
f2 << "hello";
}
The output I receive when I input r=3, for example, and the file is empty:
org:
org:
pos: -1
Also, the file remains empty. No output.
tellg() does not seem to work.
Anyone has any idea what to do here?
First of all, don't read and write to the same file. Files are opened in different modes so this won't work. But aside from that it is also better practice to parse your input, then operate on it in memory and write out the desired result. so open the file, read what is of interest (you can store a map with the lines that are interesting, or read the whole thing into memory) then do your operations on it, and write out the result.

Reading a text file into a struct array c++

This is for a homework assignment, but what I am presenting is a small test program for a chunk of my assignment.
Starting out, I am to have a list of songs in file "songs.txt". My current file looks like this.
Maneater;4;32
Whip It;2;41
Wake Me Up Before You Go-Go;3;45
The file simply contains a song title, and the duration in minutes and seconds, with the title, minutes, and seconds separated by semicolons. The full file is supposed to contain the Artists and Album as well, all separated by semicolons. Anyways, the code.
#include<iostream>
#include<cstring>
#include<fstream>
#include<cstdlib>
using namespace std;
const int CAP = 100;
const int MAXCHAR = 101;
struct songInfo
{
char title[CAP];
char durMin[CAP];
char durSec[CAP];
};
void getData(songInfo Song[], int listSize, int charSize);
int main()
{
string fileName;
songInfo Song[CAP];
ifstream inFile;
cout << "What is the file location?: ";
cin >> fileName;
inFile.open(fileName.c_str());
if (inFile.fail())
{
cout << "Cannot open file " << fileName << endl;
exit(1);
}
getData(Song, CAP, MAXCHAR);
for (int i=0;i<CAP;i++)
{
cout << Song[i].title << " - "
<< Song[i].durMin << ":"
<< Song[i].durSec << endl;
}
cout << "Press any button to continue..." << endl;
cin.get(); cin.get();
return 0;
}
void getData(songInfo Song[], int listSize, int charSize)
{
for (int i = 0; i < listSize; i++)
{
cin.get(Song[i].title, charSize, ';');
cin.get(Song[i].durMin, charSize, ';');
cin.get(Song[i].durSec, charSize, '\n');
i++;
cin.ignore();
}
}
The program compiles correctly without incident, but the output is not what I want it to be. What should happen:
Test.cpp opens songs.txt
Read the first char array into Song[i].title, delimited by ';'
Read the second char into Song[i].durMin, delimited by ';'
Read the third char into Song[i].durSec, delimited by newline
After compiling the code and running it, I get this as my output:
~/project2Test> ./test
What is the file location?: songs.txt
The program then hangs here and I have to ctrl+C out
First, what am I doing wrong?
Second, how do I go about fixing what I screwed up?
Also, as a note for class rules, I am not allowed to use any strings except for the filename. Other than that, all words must be chars.
A debugger is definitely a good thing to use for a problem like this.
Your hanging problem is occurring because in your get_data function you are using cin.get instructing your program to get input from the standard input file. You intended to use the file you defined, "inFile" not the standard input cin.
As an aside it is not clear to me why you are incrementing i twice per iteration of the for loop.
Use inFile.get() instead of cin. You need to pass inFile to the function first.
Put a print statement in the for loop to see what is happening.. A future issue that might crop up is that if you are on a Windows machine and have \r\n line endings. Unix uses \n, Windows uses \r\n

C++ : getline() function does not include last character/string when reading from a file

i have these words from a textfile each separated by a '\t' space.
I want to be able to print those words in separate lines
For example:
these are the words from the textfile:
hel lo im carlos
The result i want:
hel lo
im
carlos
The result i'm getting:
hel lo
im
here's the code:
string ReadString(ifstream &file){
char buf[1024];
file.getline(&(buf[0]), 1024, '\t');
return string(buf);
}
main(){
ifstream delimfile("new.txt");
while(1){
string words = ReadString(delimfile);
if(delimfile.eof()==true)
break;
cout << words << endl;
}
delimfile.close();
}
all the help is appreciated
Your last read will read until the end of the file (since there's no \t for it to hit) and set the EOF bit. Then you test if the EOF bit is set and break out of the loop. Changing your condition to check delimfile.fail() would fix this (because fail is set when the read actually fails).
You could also move the outputting of the word above the condition, but that presumes that the reading from the file works, which is a bad way to write your code. Similarly, having an extra tab at the end of your file would make your code work, but only makes it safe from this problem.
However, if I was going to write this myself, I would write it like so:
while (std::getline(file, words, '\t')) {
cout << words << endl;
}
Try this:
while(1)
{
string words = ReadString(delimfile);
cout << words << endl;
if(delimfile.eof()==true)
break;
//cout << words << endl;
}