I have a text file
0 Po Tom Mr 123AlphabetStreet Netherlands Wulu 123456 D01 Malaysia SmallAdventure 231112
0 Liu Jack Mr 123AlphabetStreet Italy Spain 123456 D02 Afghanistan TriersAdventure 030214
I am trying to read the txt file:Form.txt, store each line using getline into the variable foo
This is the working program
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int main()
{
fstream afile;
afile.open("Form.txt",ios::in);
string foo;
while (getline(afile,foo,'\n') );
{
cout<<foo
<<endl;
}
}
Nothing gets printed to the console output , I am expecting
0 Po Tom Mr 123AlphabetStreet Netherlands Wulu 123456 D01 Malaysia SmallAdventure 231112
0 Liu Jack Mr 123AlphabetStreet Italy Spain 123456 D02 Afghanistan TriersAdventure 030214
Instead i get
What is wrong with my code ??
You have a semicolon at the end of your while loop:
while (getline(afile, foo, '\n'));
// ^
This causes the extraction to be performed but only the when the loop ends does foo get printed. The last extraction doesn't extract anything which is why foo is empty, hence the empty output.
Related
In a varible list there are numeric as well as character values are there, how can I get only character values from it in sas. example dataline are here in only one variable list VAR1 there are values e.g:
123
xyz
457
abc
789
frf
233
gth
...
664
fgd
I have to extract only those character values(abc, xyz etc) from that whole dataline, How can I get.
See if you can use this
data _null_;
var1 = '123, xyz, 456, abc, 789, frf, 233, gth';
var2 = compbl(compress(var1, '', 'ka'));
put var2=;
run;
EDIT:
data _null_;
var1 = '123 xyz 456 abc 789 frf 233 gth
123 xyz 456 abc 789 frf 233 gth
123 xyz 456 abc 789 frf 233 gth';
var2 = compbl(compress(var1, '', 'ka'));
put var2;
run;
The question is not abundantly clear, however, if the individual values are in a single column you can use VERIFY instead of the more complicated PRXMATCH
data have;
input var1 $; datalines;
123
xyz
457
abc
789
frf
233
gth
...
664
fgd
;
data want;
set have;
where 0 = verify (trim(var1), '0123456789');
run;
VERIFY
Returns the position of the first character in a string that is not in specified data strings.
...
Details
The VERIFY function returns the position of the first character in source that is not present in any excerpt. If VERIFY finds every character in source in at least one excerpt, VERIFY returns a 0.
this code is working fine for me:
data want;
set have;
if prxmatch('/\d+\s*$/',VAR1)>0 then delete;
run;
I'm trying to read from this file file.txt which contains contents of the contestants who participated in the long jump event during the Olympic games.
The file is in the format of [First Name] [Last Name] [Nationality] [Distance]
There are 40 contestants in this file. I'm trying to organize them such that there is a vector of pointers of athletes, 40 to be precise. Then dynamically allocate them to the heap. Each athlete is one object in the vector.
Once each athlete object is entered into the vector, I wish to output all the contents of the vector onto the console through a for loop.
However, as it currently stands, in my code I do have 40 objects allocated to the vector, but its the same one being repeated 40 times. The last object is also being repeated twice for some reason.
Any help would be greatly appreciated! Thanks in advance.
Test.cpp
#include <iostream>
#include<fstream>
#include<vector>
#include<string>
#include "Person.h"
#include "Athlete.h"
using namespace std;
vector<Athlete*> athletesList(40);
//overload the operator << to be used for printing the record Objects
ostream& operator<<(ostream& out, Athlete& a) {
out << a.getFirstName() << " " << a.getLastName() << " " << a.getNationality() << " " << a.getDistance() << "\n";
return out;
}
void readAthletesFromFile() {
fstream athlethesFile;
athlethesFile.open("file.txt");
string tmpFirstName;
string tmpLastName;
string tmpNationality;
string tmpDoubleDistance;
while (!athlethesFile.eof()) {
athlethesFile >> tmpFirstName;
athlethesFile >> tmpLastName;
athlethesFile >> tmpNationality;
athlethesFile >> tmpDoubleDistance;
double tmpDistance = stod(tmpDoubleDistance);
for (int i = 0; i < 40; i++) {
athletesList[i] = new Athlete(tmpFirstName, tmpLastName, tmpNationality, tmpDistance);
}
cout << *athletesList[0];
}
}
int main()
{
readAthletesFromFile();
system("pause");
}
File.txt
Aleksandr Menkov Russia 8.09
Aleksandr Petrov Russia 7.89
Alyn Camara Germany 7.72
Arsen Sargsyan Armenia 7.62
Boleslav Skhirtladze Georgia 7.26
Christian Reif Germany 7.92
Christopher Tomlinson Great_Britain 8.06
Damar Forbes Jamaica 7.79
Eusebio Caceres Spain 7.92
George Kitchens United_States 6.84
Godfrey Khotso-Mokoena South_Africa 8.02
Greg Rutherford Great_Britain 8.08
Henry Frayne Australia 7.95
Ignisious Gaisah Ghana 7.79
Li Jinzhe China 7.77
Lin Ching-Hsuan-Taipei China 7.38
Louis Tsatoumas Greece 7.53
Luis Rivera Mexico 7.42
Marcos Chuva Portugal 7.55
Marquise Goodwin United_States 8.11
Mauro-Vinicius da-Silva Brazil 8.11
Michel Torneus Sweden 8.03
Mitchell Watt Australia 7.99
Mohamed Fathalla-Difallah Egypt 7.08
Mohammad Arzandeh Iran 7.84
Ndiss Kaba-Badji Senegal 7.66
Povilas Mykolaitis Lithuania 7.61
Raymond Higgs Bahamas 7.76
Roman Novotny Czech-Republic 6.96
Salim Sdiri France 7.71
Sebastian Bayer Germany 7.92
Sergey Morgunov Russia 7.87
Stanley Gbagbeke Nigeria 7.59
Stepan Wagner Czech-Republic 7.5
Supanara Sukhasvasti Thailand 7.38
Tyrone Smith Bermuda 7.97
Vardan Pahlevanyan Armenia 6.55
Viktor Kuznyetsov Ukraine 7.5
Will Claye United_States 7.99
Zhang Xiaoyi China 7.25
Expected Output
Ex: *athletesList[0] = Aleksandr Menkov Russia 8.09
*athletesList[10]= Godfrey Khotso-Mokoena South_Africa 8.02
Current Output
Ex: *athletesList[0] =
Aleksandr Menkov Russia 8.09
Aleksandr Petrov Russia 7.89
Alyn Camara Germany 7.72
Arsen Sargsyan Armenia 7.62
Boleslav Skhirtladze Georgia 7.26
Christian Reif Germany 7.92
Christopher Tomlinson Great_Britain 8.06
Damar Forbes Jamaica 7.79
Eusebio Caceres Spain 7.92
George Kitchens United_States 6.84
Godfrey Khotso-Mokoena South_Africa 8.02
Greg Rutherford Great_Britain 8.08
Henry Frayne Australia 7.95
Ignisious Gaisah Ghana 7.79
Li Jinzhe China 7.77
Lin Ching-Hsuan-Taipei China 7.38
Louis Tsatoumas Greece 7.53
Luis Rivera Mexico 7.42
Marcos Chuva Portugal 7.55
Marquise Goodwin United_States 8.11
Mauro-Vinicius da-Silva Brazil 8.11
Michel Torneus Sweden 8.03
Mitchell Watt Australia 7.99
Mohamed Fathalla-Difallah Egypt 7.08
Mohammad Arzandeh Iran 7.84
Ndiss Kaba-Badji Senegal 7.66
Povilas Mykolaitis Lithuania 7.61
Raymond Higgs Bahamas 7.76
Roman Novotny Czech-Republic 6.96
Salim Sdiri France 7.71
Sebastian Bayer Germany 7.92
Sergey Morgunov Russia 7.87
Stanley Gbagbeke Nigeria 7.59
Stepan Wagner Czech-Republic 7.5
Supanara Sukhasvasti Thailand 7.38
Tyrone Smith Bermuda 7.97
Vardan Pahlevanyan Armenia 6.55
Viktor Kuznyetsov Ukraine 7.5
Will Claye United_States 7.99
Zhang Xiaoyi China 7.25
Zhang Xiaoyi China 7.25
Avoid calling new and delete explicitly to dynamically allocate memory. You don't need it in combination with STL containers. A container allocates and manages the memory on the heap.
The for loop is not necessary. For each element you read you overwrite all elements with the last read element.
You print the first element from the vector for each element you read:
Change
cout << athletesList[0];
to
cout << athletesList.back();
You can't
while (!athlethesFile.eof()) {
because eof is set after you tried to read and it failed. You have to check if the read was successful after the read. Why is iostream::eof inside a loop condition (i.e. while (!stream.eof())) considered wrong?
Don't include Person.h if you don't use it.
You should avoid system(). Usually it's not portable.
In your current code you read 40 elements in a loop. In each loop iteration you allocate 40 elements for that vector. That means that you allocate memory for 1600 elements. You do not clean that up. That is a serious memory leak.
#include "Athlete.h"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using std::cerr;
using std::cout;
using std::fstream;
using std::ostream;
using std::string;
using std::vector;
//overload the operator << to be used for printing the record Objects
ostream& operator<<(ostream& out, Athlete& a) {
out << a.getFirstName() << " " << a.getLastName() << " " << a.getNationality() << " " << a.getDistance() << "\n";
return out;
}
auto readAthletesFromFile() {
vector<Athlete> athletesList;
athletesList.reserve(40);
fstream athlethesFile("file.txt");
if (!athlethesFile) {
cerr << "Could not open file\n";
return athletesList;
}
string tmpFirstName;
string tmpLastName;
string tmpNationality;
string tmpDoubleDistance;
while (true) {
athlethesFile >> tmpFirstName;
athlethesFile >> tmpLastName;
athlethesFile >> tmpNationality;
athlethesFile >> tmpDoubleDistance;
if (!athlethesFile) break;
auto tmpDistance = stod(tmpDoubleDistance);
athletesList.emplace_back(tmpFirstName, tmpLastName, tmpNationality, tmpDistance);
//cout << athletesList.back();
}
return athletesList;
}
int main() {
auto athletesList = readAthletesFromFile();
cout << athletesList[9];
}
I'm going to posit that #Thomas Sablik started out in the right direction, but then at least in my opinion, he kind of dropped the ball, so to speak. In particular, I think this part:
//overload the operator << to be used for printing the record Objects
ostream& operator<<(ostream& out, Athlete& a) {
out << a.getFirstName() << " " << a.getLastName() << " " << a.getNationality() << " " << a.getDistance() << "\n";
return out;
}
...is absolutely great! Even if I really wanted to say bad things about it, just about the worst I could probably come up with would be that the Athlete should be passed by const reference (and being honest, that's a pretty minor quibble).
So we have great code to write an Athlete object. But for some reason, our code for reading Athlete objects isn't the same at all. Why not?
I believe the code for reading should be almost a mirror image of the code for writing.
std::istream &operator>>(std::istream &in, Athlete &a) {
in >> a.firstName >> a.lastName >> a.nationality >> a.distance;
return in;
}
Using that, we can leave almost all the memory management to the standard library. In fact, there's probably no need for the readAthletesFromFile at all. Reading in a file becomes something like this:
std::ifstream input("file.txt");
std::vector<Athlete> list{std::istream_iterator<Athlete>(input), {}};
That's it. That reads in the entire file. Well, it could stop sooner if it encountered bad input, but it'll read as much as it can anyway.
So let's consider an example: we'll read in the data and print out the top 5 distances (and the information for each of those records):
class Athlete {
public:
friend std::ostream& operator<<(std::ostream& out, Athlete const& a) {
out << a.firstName << " " << a.lastName << " " << a.nationality << " " << a.distance << "\n";
return out;
}
friend std::istream &operator>>(std::istream &in, Athlete &a) {
in >> a.firstName >> a.lastName >> a.nationality >> a.distance;
return in;
}
bool operator<(Athlete const &other) const {
return distance < other.distance;
}
private:
std::string firstName, lastName, nationality;
double distance;
};
int main() {
std::ifstream in("file.txt");
std::vector<Athlete> list{std::istream_iterator<Athlete>(in), {}};
std::partial_sort(list.begin(), list.end()-5, list.end());
std::copy(list.end()-5, list.end(), std::ostream_iterator<Athlete>(std::cout, ""));
}
Result:
Mauro-Vinicius da-Silva Brazil 8.11
Marquise Goodwin United_States 8.11
Aleksandr Menkov Russia 8.09
Greg Rutherford Great_Britain 8.08
Christopher Tomlinson Great_Britain 8.06
Using regular expression howto obtain all combination of 2 characters on a string?
Example: "abcdefghi", Result: ab,bc,cd,de,ef
Using 3 chars: abc,bcd,cde,def...
I try with: /.{2}/g but is not recursive, only match ab,cd,ef but not bc,de, etc.
Howto make this?
You can try this:
(?=(\w{2}))\w
Sample regex example here.
Java Sample Code:
public static void printVal(String str,int length)
{
final String regex="(?=(\\w{"+length+"}))\\w";
final Pattern pattern=Pattern.compile(regex,Pattern.MULTILINE);
final Matcher matcher=pattern.matcher(str);
System.out.println("length :"+length);
while(matcher.find())
{
System.out.println(matcher.group(1));
}
}
Sample Input:
printVal("abcdefghi",2);
printVal("abcdefghi",3);
printVal("abcdefghi",4);
Sample Output:
length :2
ab
bc
cd
de
ef
fg
gh
hi
length :3
abc
bcd
cde
def
efg
fgh
ghi
length :4
abcd
bcde
cdef
defg
efgh
fghi
I have a project where I am reading data from a text file in c++ which contains a person's name and up to 4 numerical numbers like this. (each line has an entry)
Dave Light 89 71 91 89
Hua Tran Du 81 79 80
I am wondering if regex would be an efficient way of splitting the name and numerical values or if I should find an alternative method.
I would also like to be able to pick up any errors in the text file when reading each entry such as a letter instead of a number as if an entry like this was found.
Andrew Van Den J 88 95 85
You should better use a separator instead of space. The separator could be :, |, ^ or anything that cannot be part of your data. With this approach, your data should be stored as:
Dave Light:89:71:91:89
Hua Tran Du:81:79:80
And then you can use find, find_first_of, strchr or strstr or any other searching (and re-searching) to find relevant data.
This non-regex solution:
std::string str = "Dave Light 89 71 91 89";
std::size_t firstDig = str.find_first_of("0123456789");
std::string str1 = str.substr (0,firstDig);
std::string str2 = str.substr (firstDig);
would give you the letter part in str1 and the number part in str2.
Check this code at ideone.com.
It sounds like it's something like this you want...(?) I'm not quite sure what kind of errors you mean to pick. As paxdiablo pointed out, a name could be quite complex, so getting the letter part probably would be the safest.
Try this code.
#include <iostream>
#include <regex>
#include <string>
#include <vector>
int main(){
std::vector<std::string> data {"Dave Light 89 71 91 ","Hua Tran Du 81 79 80","zyx 1 2 3 4","zyx 1 2"};
std::regex pat {R"((^[A-Za-z\s]*)(\d+)\s*(\d+)\s*(\d+)(\s*)$)"};
for(auto& line : data) {
std::cout<<line<<std::endl;
std::smatch matches; // matched strings go here
if (regex_search(line, matches, pat)) {
//std::cout<<"size:"<<matches.size()<<std::endl;
if (matches.size()==6)
std::cout<<"Name:"<<matches[1].str()<<"\t"<<"data1:"<<matches[2].str()<<"\tdata2:"<<matches[3].str()<<"\tdata3:"<<matches[4].str()<<std::endl;
}
}
}
With regex number of lines code reduced greatly. Main trick in regex is using right pattern.
Hope this will help you.
I have TEXT File and extracted every line of data from text file. The extracted data is stored to list of string then I iterate loop to List of string to manipulate and validate the data extracted. Now every line of string I extracted, I want to validate if that line of string is contain 1). I used RegEx for this but it gives me no luck. (Please see image below)
My Text File
Code
Dim strRegexPattern As String = "^\d{1,6}[)]\s$"
Dim myRegex As New Regex(strRegexPattern, RegexOptions.None)
Dim _strMatch As Match = myRegex.Match(line) '<-- i use for each line as string in listOfExtractedLines
If _strMatch.Success Then
MsgBox(_strMatch.Value)
End If
String extracted from text file(with formatting and spaces)
Title : 8015B DRO(C10-C28) - ORO (C18-C36)
Column01 Col2 Col3 Column04 Col5 Col06 Col(007)
--------------------------------------------------------------------------
Intxxxxx xxxxxxxxx
1) zzzzzzzzzzzzzzzzzz 4.464 168 212614 25.00 xyz 0.00
33) aaaaaaaaaaaaaaaaaaa 4.818 114 330529 25.00 xyz 0.00
51) bbbbbbbbbbbbbbbb 6.742 117 318044 25.00 xyz 0.00
64) cccccccccccccccccccccc 8.397 152 186712 25.00 xyz 0.00
21) Endosulfan Sulfa 12.51 13 918.2E6 840.8E6 106.315
22) Endrin Ketone 13.11 14 143.4E6 992.2E6 104.978
^.*?\s\d{1,6}[)]\s.*$
Try this to match the whole line.
Edit:
(?:^|\s+)\d{1,6}[)]\s.*$