Trouble shooting reading CSV File code - c++

I've been trying to trouble shoot this code for a couple of days now with no luck. I'm trying to read a CSV file (separated by a comma) that looks like this. I want to output the 100 spot (second row second column).
apple,party11,
0,0.1,
0.1,**100**,
//-Line 4 is empty-
My Code :
void Info() {
Input1 = CSVfile("File1.csv");
Input2 = CSVfile("File2.csv");
}
double CSVfile(string cvsfilein) {
ifstream file;
file.open(cvsfilein);
if (file.fail()) {
printf("----------Error no CSV File----------------");
return 0;
}
vector<vector<string>> csvfile;
double needvalue;
while (file) {
string filevalue1;
if (!getline(file, filevalue1)) {
cout << "failed heree1 " << endl;
return -2;
break;
}
** // Never get past here**
cout
<< "filevalue1 " << filevalue1 << endl;
istringstream iss(filevalue1);
vector<string> record;
while (iss) {
string filevalue2;
if (!getline(iss, filevalue2, ',')) {
if (filevalue2.empty())
continue;
cout << "failed heree2 " << endl;
return -2;
break;
}
record.push_back(filevalue2);
cout << "filevalue2 " << filevalue2 << endl;
}
csvfile.push_back(record);
needvalue = atof(record[3].c_str()); // Converts the string to number
cout << needvalue << endl; // just to check
return needvalue;
file.close();
}
}
I never seem to get passed the first if (!getline(file, filevalue1)). I've tried using if (filevalue1.empty()) continue; and it doesn't seem to continue the code.. just stops it.

The primary issue is the placement of file.close(), and secondary issues relate to various bits of unreachable code. This mildly modified version of your code seems to work, even managing not to crash on the empty line at the end of the file(s) — I used two identical data files.
#include <cstdlib>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
using namespace std;
double CSVfile(string cvsfilein);
void Info();
double Input1;
double Input2;
void Info() {
Input1 = CSVfile("File1.csv");
Input2 = CSVfile("File2.csv");
}
double CSVfile(string cvsfilein) {
ifstream file;
file.open(cvsfilein);
if (file.fail()) {
cerr << "----------Error no CSV File----------------\n";
return 0;
}
vector<vector<string>> csvfile;
while (file) {
string filevalue1;
if (!getline(file, filevalue1)) {
cerr << "failed heree1 " << endl;
return -2;
break;
}
cout << "filevalue1 " << filevalue1 << endl;
istringstream iss(filevalue1);
vector<string> record;
while (iss) {
string filevalue2;
if (!getline(iss, filevalue2, ',')) {
if (filevalue2.empty())
continue;
cerr << "failed heree2 " << endl;
return -2;
}
record.push_back(filevalue2);
cout << "filevalue2 " << filevalue2 << endl;
}
csvfile.push_back(record);
//double needvalue = atof(record[3].c_str()); // Converts the string to number
//cout << needvalue << endl; // just to check
//return needvalue;
//file.close();
}
file.close();
return 0;
}
int main()
{
Info();
return 0;
}
Sample output:
filevalue1 apple,party11,
filevalue2 apple
filevalue2 party11
filevalue1 0,0.1,
filevalue2 0
filevalue2 0.1
filevalue1 0.1,100,
filevalue2 0.1
filevalue2 100
filevalue1
failed heree1
filevalue1 apple,party11,
filevalue2 apple
filevalue2 party11
filevalue1 0,0.1,
filevalue2 0
filevalue2 0.1
filevalue1 0.1,100,
filevalue2 0.1
filevalue2 100
filevalue1
failed heree1
The needvalue computation crashes the program on the empty line (dereferencing a null pointer in strtod() called from within atof()). That's because there isn't a record[3] entry to convert to a string — not unreasonable.

It worked for me too (exactly until the conversion from string to double).
Firts of all getline returns an istream& so don't put it inside an if.
Now, If the "failed heree1" error isn't printed at all use try & catch.
Moreover, check the error bits:
try {
getline(file, filevalue1);
} catch(ifstream::failure e) {
cerr << "Exception happened: " << e.what() << endl
<< "Error bits are: "
<< "\nfailbit: " << file.fail()
<< "\neofbit: " << file.eof()
<< "\nbadbit: " << file.bad() << endl;
}
eofbit - The end of the source of characters is reached during its operations.
failbit - The input obtained could not be interpreted as a valid textual representation of an object of this type. Notice that some eofbit cases will also set failbit.
badbit - An error other than the above happened.
it failbit is on i would put my money on the csv-file's encoding.
source: http://www.cplusplus.com/reference/string/string/getline/

Related

readFile function not working on second iteration with different argument - c++

I've written a readFile function for a project I'm working on. I call it once, load in a file and read in it's contents - works fine
However, when I try to load it a second time, attempting to change the file name - it loads it in, saves it to a static string 'path' that I access in a different function - but then the function is not printing the data
The question is, how do I change the file name, and read it in successfully on the second iteration? The part that has me stumped is that it works once, but not twice
Ive attempted to use cin.ignore(); cin.clear(); cin.sync() on the second iteration of fileName function - but none of them allow a separate file to be read successfully.
Minimum Reproducible Example:
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <vector>
#include <sstream>
#include <iomanip>
#include <iostream>
using namespace std;
static string path;
string opt;
void readFile();
int fileName();
void menu() { // put in while loop - while True
cout << "----------------------" << endl;
cout << "R(ead) -" << "Read File" << endl;
cout << "F(ile) -" << "Set Filename" << endl;
cout << "\nPlease select from the above options" << endl;
cin >> opt;
cout << "\nInput entered: " << opt << endl;
if (opt == "R") {
readFile();
}
if (opt == "F") {
fileName();
}
}
void readFile() { // doing this twice
ifstream readFile;
readFile.open(path);
if (!readFile.is_open()) {
cout << "Could not read file" << endl;
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << endl;
}
}
readFile.clear();
readFile.close();
menu();
}
int fileName() {
cout << "File path: ";
if (path != "") {
cin.ignore();
cin.clear();
cin.sync();
}
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << endl;
return 1;
}
cout << "(File loaded)" << endl;
cout << "Path contains: " << path << endl;
file.clear();
file.close();
menu();
}
int main()
{
fileName();
}
Sample text, saved as txt file and read in using path:
Data1.txt
// standard test file
123,Frodo inc,2006, lyons,"1,021,000.16",0.0,
U2123,Sam Inc,2006, lyons,"21,600.00",13.10,123
A721,Merry Inc,2604, Kingston,"21,600.10",103.00,
U2122,Pippin Inc,2612, reid,"21,600.00",0
U1123,Huckelberry corp,2612, Turner,"21,600.00",13.10,
Data2.txt
7101003,Mike,23 boinig road,2615,48000,12000,0
7201003,Jane Philips,29 boinig cresent,2616,47000,12000,0
7301003,Philip Jane,23 bong road,2615,49000,000,0
7401004,Peta,23 bong bong road,2615,148000,19000,0
7101205,Abdulla,23 Station st,2615,80000,21000,0
The problem comes from reading in one, and trying to read in the other after the first has been executed.
Enter Filename
Hit Readfile
Return to menu, hit Set Filename
Change to Data2.txt
Readfile again. Not working
My tutor told me "That's not how functions work in c++" but didn't elaborate further, and is unavailable for contact.
In general, do not use global variables. The path variable should be passed as a parameter, not kept as a global variable altered between function calls, as this leads to many side effects and is the source of countless bugs. See the following refactoring:
void menu() { // put in while loop - while True
while(true)
{
//Keep this as a local variable!
std::string opt;
std::string filename;
cout << "----------------------\n";
cout << "R(ead) -" << "Read File\n";
cout << "F(ile) -" << "Set Filename\n";
cout << "\nPlease select from the above options\n";
cin >> opt;
cout << "\nInput entered: " << opt << '\n';
if (opt == "R") {
readFile(filename);
}
if (opt == "F") {
filename = getFileName();
}
}
}
void readFile(const std::string & filename) {
ifstream readFile;
readFile.open(filename);
if (!readFile.is_open()) {
cout << "Could not read file " << filename << '\n';
}
string str;
int i = 0;
while (getline(readFile, str))
{
if (str[0] != '/')
{
cout << "DEBUG: Line is - " << str << '\n';
}
}
readFile.close();
//just return to get back to menu
return;
}
std::string getFileName() {
cout << "File path: ";
std::string path;
getline(cin, path);
ifstream file(path.c_str());
if (!file) {
cout << "Error while opening the file" << '\n';
//Instead of returning an error code use an exception preferably
}
cout << "(File loaded)" << '\n';
cout << "Path contains: " << path << '\n';
file.close();
return path;
}
Other notes:
Ideally, do input in output in just one function, not all three as it gets confusing exactly what each function is responsible for.
If you want something to hold a file and print the contents, you can use an class.
The file is checked if it is openable twice, not really any reason to do this just delegate that responsibility to one function.
One of the best things about C++ is RAII and deterministic lifecycles for objects and primitives - use it!! Do not give everything a long life with global variables - use smart parameters and return values instead.

getline and testing EOF at once

I would like to ask about my problem I tried to read Getline and EOF Question but did not help.
Problem is I have no idea where could be mistake here:
Is there some problem with used function ( getline or checking EOF ) ?
If there is no text in text.txt file it says there something was found. But I have no idea why or where I made a mistake ...
What I want is: Search for string and if there is no text in txt file I want it to says EOF or something. It still says - even if file is empty - string I was looking for was found in line one , position one - for example
I am puting there code:
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int openFile(void);
int closeFile(void);
int getTime(void);
int findTime();
int findDate();
int stringFind(string);
bool getOneLine(void);
string what;
bool ifound = false;
string foundstring;
string filename ;
fstream inputfile;
string sentence ;
size_t found ;
string foundTime ;
string foundDate ;
bool timeIsHere = false;
bool dateIsHere = false;
int iterTime = 0;
int iterDate = 0;
int line = 0;
int main (void){
sentence.clear();
cout << " Enter the file name:" << endl;
openFile();
while (getOneLine() != false) {
stringFind("Time");
}
cout << "END OF PROGRAM" << endl;
system("PAUSE");
///getTime();
closeFile();
system("PAUSE");
}
int closeFile(void) {
inputfile.close();
cout << " File: " << filename << " - was closed...";
return 0;
}
int openFile(void) {
cout << " Insert file name in program directory or full path to desired file you want to edit:"<<endl;
cout << " Do not use path with a space in directory address or filename ! " << endl;
cout<<" ";
getline(cin, filename);
inputfile.open(filename, ios::in);
cout <<" file_state: " << inputfile.fail();
if (inputfile.fail() == 1) {
cout << " - Cannot open your file" << endl;
}
else cout << " - File was openned sucesfully"<< endl;
return 0;
}
int stringFind(string what) {
cout << " I am looking for:" << what << endl;
found = what.find(sentence);
if (found == string::npos) {
cout << " I could not find this string " << endl;
}
else if(found != string::npos){
cout << " substring was found in line: " << line + 1 << " position: " << found + 1 << endl << endl;
ifound = true;
foundstring = sentence;
}
return 0;
}
bool getOneLine(void) {
if (inputfile.eof()) {
cout << "END OF FILE" << endl << endl;
return false;
}
else{
getline(inputfile, sentence);
cout << "next sentence is: "<< sentence << endl;
return true;
}
}
I am newbie and I have no one to ask - personally . I tried to edit While cycle and IF's to make sure that I did not make a serious mistake but I have no idea.
I tried it with for example sample.txt and this file was empty.
Always test whether input succeeded after the read attempt! The stream cannot know what you are attempting to do. It can only report whether the attempts were successful so far. So, you'd do something like
if (std::getline(stream, line)) {
// deal with the successful case
}
else {
// deal with the failure case
}
In the failure case you might want to use use eof() to determine whether the failure was due reaching the end of the stream: Having reached the end of file and, thus, std::ios_base:eofbit being set is often not an error but simply the indication that you are done. It may still be an error, e.g., when it is known how many lines are to be read but fewer lines are obtained.
Correct way to use getline() and EOF checking would be like this:
bool getOneLine(void) {
if (getline(inputfile, sentence)) {
cout << "next sentence is: "<< sentence << endl;
return true;
}
if (inputfile.eof())
cout << "EOF reached" << endl;
else
cout << "Some IO error" << endl;
return false;
}
You have one mistake here:
found = what.find(sentence);
You are seeking inside of what for the sentence. If sentence is empty, it will be found.
Change it to
found = sentence.find(what);
You should definitivly learn how to use a debugger. That way you would find such issues pretty fast!

Reading from a file C++ Ifstream

I am trying to do a problem using dynamic programming to find which items to select from a text file under a certain weight capacity while maximizing value. The file is in the format:
item1, weight, value
item2, weight, value
With a variable number of items. I am having a problem reading the file in the main method, where I am trying to error check for bad input. My problem comes from when I check if the weight is either missing, or is a string instead of an int. I can't figure out how to check separately for a string or if there is nothing in that spot. I am supposed to output a different error depending on which it is. Thanks.
int main(int argc, char * const argv[])
{
std::vector<Item> items;
if (argc != 3)
{
std::cerr << "Usage: ./knapsack <capacity> <filename>";
return -1;
}
int capacity;
std::stringstream iss(argv[1]);
if (!(iss >> capacity) || (capacity < 0))
{
std::cerr << "Error: Bad value '" << argv[1] << "' for capacity." << std::endl;
return -1;
}
std::ifstream ifs(argv[2]);
if (ifs.is_open())
{
std::string description;
unsigned int weight;
unsigned int value;
int line = 1;
while (!ifs.eof())
{
if (!(ifs >> description))
{
std::cerr << "Error: Line number " << line << " does not contain 3 fields." << std::endl;
return -1;
}
if (!(ifs >> weight))
{
if (ifs.eof())
std::cerr << "Error: Line number " << line << " does not contain 3 fields." << std::endl;
else
std::cerr << "Error: Invalid weight '" << ifs << "' on line number " << line << "." << std::endl;
return -1;
}
else if (!(ifs >> weight) || (weight < 0))
{
std::cerr << "Error: Invalid weight '" << ifs << "' on line number " << line << "." << std::endl;
return -1;
}
if (!(ifs >> value))
{
if (ifs.eof())
std::cerr << "Error: Line number " << line << " does not contain 3 fields." << std::endl;
else
std::cerr << "Error: Invalid value '" << ifs << "' on line number " << line << "." << std::endl;
return -1;
}
else if (!(ifs >> value) || (value < 0))
{
std::cerr << "Error: Invalid value '" << ifs << "' on line number " << line << "." << std::endl;
return -1;
}
Item item = Item(line, weight, value, description);
items.push_back(item);
line++;
}
ifs.close();
knapsack(capacity, items, items.size());
}
else
{
std::cerr << "Error: Cannot open file '" << argv[2] << "'." << std::endl;
return -1;
}
return 0;
}
I think better approach will be using getline function, by which you will take a whole line and then you can try to split it into three strings. If three parts are not found or any of the three parts is not in a right format you can output an error.
An example code is give below,
#include<fstream>
#include<iostream>
#include<vector>
#include <sstream>
#include<string>
using namespace std;
void split(const std::string &s, std::vector<std::string> &elems, char delim) {
elems.clear();
std::stringstream ss(s);
std::string item;
while (std::getline(ss, item, delim)) {
elems.push_back(item);
}
}
int main()
{
vector<string> elems;
ifstream fi("YOUR\\PATH");
string inp;
while(getline(fi, inp))
{
split(inp, elems, ' ');
if(elems.size() != 3)
{
cout<<"error\n";
continue;
}
int value;
bool isint = istringstream(elems[1])>>value;
if(!isint)
{
cout << "error\n";
continue;
}
cout<<"value was : " << value << endl;
}
return 0;
}
You could read the whole line at once and check it's format using regular expressions.

Data doesn't load into c++ vector correctly

I am trying to load a text file and import the contents into a vector of structs.
Here are my definitions
typedef struct
{
string pcName, pcUsername, pcPassword, pcMessage, pcAdvertisement; //I know that
//this is incorrect convention. It was originally a char*
}
ENTRY;
vector<ENTRY> entries;
fstream data;
Here is my display data function
void DisplayData()
{
std::cout << (int)(entries.size() / 5) <<" entries" << endl;
for(int i = 1; i <=(int)entries.size()/5; i++)
{
cout << endl << "Entry " << i << ":" << endl
<< "Name: " << entries[i].pcName << endl
<< "Username: " << entries[i].pcUsername << endl
<< "Password: " << entries[i].pcPassword << endl
<< "Message: " << entries[i].pcMessage << endl
<< "Advertisement: " << entries[i].pcAdvertisement << endl;
}
}
and here is my Load Data function
bool LoadData(const char* filepath)
{
std::string lineData ;
int linenumber = 1 ;
data.open(filepath, ios::in);
ENTRY entry_temp;
if(!data.is_open())
{
cerr << "Error loading file" << endl;
return false;
}
while(getline(data, lineData))
{
if(linenumber==1) {entry_temp.pcName = lineData;}
else if(linenumber==2) {entry_temp.pcUsername = lineData;}
else if(linenumber==3) {entry_temp.pcPassword = lineData;}
else if(linenumber==4) {entry_temp.pcMessage = lineData;}
else if(linenumber==5) {entry_temp.pcAdvertisement = lineData;}
entries.push_back(entry_temp);
if(linenumber == 5)
{
linenumber = 0;
}
linenumber++;
}
data.close();
puts("Database Loaded");
return true;
}
Here is the text file I am loading:
Name1
Username1
Password1
Message1
Ad1
And here is the result of the display data function after calling load data:
1 entries
Entry 1:
Name: Name1
Username Username1
Password:
Message:
Advertisement:
As you can see, the first two load but the last three don't. When I did this with an array instead of a vector, it worked fine so I don't know what I'm doing wrong. Thanks.
I suggest that you read each line directly into the data field where it goes:
getline(data, entry_temp.pcName);
getline(data, entry_temp.pcUsername);
getline(data, entry_temp.pcPassword);
getline(data, entry_temp.pcMessage);
getline(data, entry_temp.pcAdvertisement);
entries.push_back(entry_temp);
This makes your intent much clearer than your current while loop. It also creates a single entry for all 4 input lines rather than one for each input line (with the other three blank). Now you can read several "entries" by using a while loop that checks if you have reached the end of the file.
Doing this will also make printing out the data much easier since the vector will have exactly the number of entries rather than five times as many as you expect (which also eats up a lot more memory than you need to).
Your DisplayData function is a little weird, and so is your LoadData.
Your LoadData pushes back a new copy of the current ENTRIES entry with every line. Your DisplayData starts at 1 (which is not the beginning of any vector or array), and iterates only up to the 1/5th entry of the entire vector.
This needs a heavy rework.
First, the size() member of any standard container returns the number of elements that it contains, and will not take the number of fields in a contained struct into account.
For future reference, you'll want to post your question in a complete, standalone example that we can immediately compile to help. (see http://sscce.org/)
Try this modified data, which runs correctly, and see if you can tell what is being done differently:
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
using namespace std;
typedef struct
{
string pcName, pcUsername, pcPassword, pcMessage, pcAdvertisement;
}
ENTRY;
vector<ENTRY> entries;
fstream data;
bool LoadData(const char* filepath)
{
std::string lineData ;
int linenumber = 1 ;
data.open(filepath, ios::in);
ENTRY entry_temp;
if(!data.is_open())
{
cerr << "Error loading file" << endl;
return false;
}
while(getline(data, lineData))
{
if(linenumber==1) {entry_temp.pcName = lineData;}
else if(linenumber==2) {entry_temp.pcUsername = lineData;}
else if(linenumber==3) {entry_temp.pcPassword = lineData;}
else if(linenumber==4) {entry_temp.pcMessage = lineData;}
else if(linenumber==5) {entry_temp.pcAdvertisement = lineData;}
if(linenumber == 5)
{
entries.push_back(entry_temp);
linenumber = 0;
}
linenumber++;
}
data.close();
puts("Database Loaded");
return true;
}
void DisplayData()
{
std::cout << entries.size() <<" entries" << endl;
for(int i = 0; i < entries.size(); i++)
{
cout << endl << "Entry " << i << ":" << endl
<< "Name: " << entries[i].pcName << endl
<< "Username: " << entries[i].pcUsername << endl
<< "Password: " << entries[i].pcPassword << endl
<< "Message: " << entries[i].pcMessage << endl
<< "Advertisement: " << entries[i].pcAdvertisement << endl;
}
}
int main()
{
LoadData("/tmp/testdata");
DisplayData();
return (0);
}
While I think #code-guru has the right idea, I'd take the same idea just a little further, and make your code work a little more closely with the standard library. I'd do that by reading a data item with a stream extractor, and displaying it with stream inserter. So, the extractor would look something like this:
std::istream &operator>>(std::istream &is, ENTRY &e) {
getline(is, e.pcName);
getline(is, e.pcUsername);
getline(is, e.pcPassword);
getline(is, e.pcMessage);
getline(is, e.pcAdvertisement);
return is;
}
..and the inserter would look something like this:
std::ostream &operator<<(std::ostream &os, ENTRY const &e) {
os << e.pcName << "\n";
os << e.pcUsername << "\n";
os << e.pcPassword << "\n";
os << e.pcMessage << "\n";
os << e.pcAdvertisement << "\n";
return os;
}
With those in place, loading and displaying the data becomes fairly straightforward.
Load the data:
std::ifstream in("yourfile.txt");
std::vector<ENTRY> data((std::istream_iterator<ENTRY>(in)),
std::istream_iterator<ENTRY>());
Display the data:
for (auto const & e: data)
std::cout << e << "\n";
For the moment, I haven't tried to duplicate the format you were using to display the data -- presumably the modifications for that should be fairly obvious.

Issue regarding size_t

If you go in my post history you'll see that i'm trying to develop an interpreter for a language that i'm working on. I want to use size_t using two different codes, but they all return nothing.
Here is the post of what i was trying: http://stackoverflow.com/questions/1215688/read-something-after-a-word-in-c
When i try to use the file that i'm testing it returns me nothing. Here is the sample file(only a print function that i'm trying to develop in my language):
print "This is a print function that i'm trying to develop in my language"
But remember that this is like print in Python, what the user type into the quotes(" ") is what have to be printed to all, remember that the user can choose what put into the quotes, then don't put something like a simple cout, post something that reads what is inside the quotes and print it to all. But here is the two test codes to do this, but all of they don't returns nothing to me:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main( int argc, char* argv[] )
{
// Error Messages
string extension = argv[ 1 ];
if(argc != 2)
{
cout << "Error syntax is incorrect!\nSyntax: " << argv[ 0 ] << " <file>\n";
return 0;
}
if(extension[extension.length()-3] != '.')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-2] != 't')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-1] != 'r')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
// End of the error messages
ifstream file(argv[ 1 ]);
if (!file.good()) {
cout << "File " << argv[1] << " does not exist.\n";
return 0;
}
string linha;
while (!file.eof())
{
getline(file, linha);
if (linha == "print")
{
size_t idx = linha.find("\""); //find the first quote on the line
while ( idx != string::npos ) {
size_t idx_end = linha.find("\"",idx+1); //end of quote
string quotes;
quotes.assign(linha,idx,idx_end-idx+1);
// do not print the start and end " strings
cout << "quotes:" << quotes.substr(1,quotes.length()-2) << endl;
//check for another quote on the same line
idx = linha.find("\"",idx_end+1);
}
}
}
return 0;
}
The second:
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>
using namespace std;
int main( int argc, char* argv[] )
{
// Error Messages
string extension = argv[ 1 ];
if(argc != 2)
{
cout << "Error syntax is incorrect!\nSyntax: " << argv[ 0 ] << " <file>\n";
return 0;
}
if(extension[extension.length()-3] != '.')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-2] != 't')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
if(extension[extension.length()-1] != 'r')
{
cout << "Extension not valid!" << endl;
cout << "Default extension *.tr" << endl;
return 0;
}
// End of the error messages
ifstream file(argv[ 1 ]);
if (!file.good()) {
cout << "File " << argv[1] << " does not exist.\n";
return 0;
}
string linha;
while (!file.eof())
{
getline(file, linha);
if (linha == "print")
{
string code = " print \" hi \" ";
size_t beg = code.find("\"");
size_t end = code.find("\"", beg+1);
// end-beg-1 = the length of the string between ""
cout << code.substr(beg+1, end-beg-1);
}
}
return 0;
}
And here is what is printed in the console:
ubuntu#ubuntu-laptop:~/Desktop/Tree$ ./tree test.tr
ubuntu#ubuntu-laptop:~/Desktop/Tree$
Like i said, it prints me nothing.
See my post in D.I.C.: http://www.dreamincode.net/forums/showtopic118026.htm
Thanks,
Nathan Paulino Campos
Your problem is the line
if (linha == "print")
which assumes the entire line just read in is "print", not that the line STARTS with print.
Also, why would you use 3 separate checks for a .tr extension, vs. just checking the end of the filename for ".tr"? (You should also be checking that argv[1] is long enough before checking substrings...)
getline(file, linha) will read an entire line from the file, so linha never be equal to print.