I have have the following problem:
When I drag and drop a file to my tool (exe) when ifstream fails to open the file.
If I give it manually though the console it works!
I don't get where the diffenence is, because I am cutting the path and passing just the filename.
Have a look at the code:
int main(int argc, char* argv[]) {
if (argc < 2) {
cout
<< "ERROR: Wrong amount of arguments! Give at least one argument ...\n"
<< endl;
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
exit(1);
return 0;
}
vector<string> files;
for (int g = 1; g < argc; g++) {
string s = argv[g];
cout<<"parameter at: " << g << " = " << argv[g] << "\n" << endl;
string filename = "";
int pos = s.find_last_of("\\", s.size());
if (pos != -1) {
filename.append(s.substr(pos + 1));
// cout<<" cutted path: " << s.substr(0,s.size()-filename.size()) << endl;
// cout << "argv[1] " << argv[1] << endl;
cout << "\n filename: " << filename << "\t pos: " << pos << endl;
files.push_back(filename);
}
files.push_back(s);
}
for (unsigned int k = 0; k < files.size(); k++)
{
cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
Converter a(files.at(k).c_str());
a.getCommandsFromCSV();
a.saveConvertedFile();
}
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
return 0;
}
It fails already on the constructor:
Converter::Converter(const char* file) {
filename = file;
myfile.open(filename.c_str(), ios_base::in);
cout << (myfile ? "open successful on constructor " : "some error on constructor");
cin.ignore();
trace_raw = "";
}
You have any idea why?
UPDATE:
The file as parameter works now. The solution was to leave the full path.
Anyway I have the same error on a hard coded file. I thought it may be the same that's why I added .\ at the beginning of the file name... without success.
The code:
void GenericCommandConverter::getATCommandsFromCSV() {
cout << "\t| +++++++++++getATCommandsFromCSV() started+++++++++++++ |"
<< endl;
/*
* CSV file name is hardcoded
*/
string filename_csv = ".\\test.csv";
string commands = "";
int pos_start = 0;
int pos_end = 0; // "|"
int substrLength = 0;
int separator_count = 0;
char c;
vector<string> lines;
vector<string> commandList;
vector<vector<string> > linesSeparated;
ifstream csvFile;
csvFile.open(filename_csv.c_str(), ios_base::in);
cout << (myfile ? "open successful on getATCommandsFromCSV " : "some error on getATCommandsFromCSV ");
cin.ignore();
...
UPDATE2:
The solution was: on dropping a file to the exe, the "root" folder changes to the one where the dropped file comes from. Giving the hardcoded file the path from the *.exe solved it!
I am guessing your current directory is wrong. Don't cut the path off. Anyway you should do error checking / debugging to see why it couldn't open the file. Diligent debugging is essential for solving problems without having to make blind guesses.
Related
int main(int argc, char *argv[]) {
ifstream inFile;
int numOfLines = 0, numOfTokens = 0, numOfStrings = 0, maxStringLength = 0, l = 0, fileCount=0, mostCommonCount=0;
string inputFile, mostCommonList="", word;
for(int i = 1; i < argc; i++){
if(strpbrk(argv[i] , "-")){
if(flags.find(string(argv[i]))!=flags.end()) flags[string(argv[i])] = true;
else{
cerr << "INVALID FLAG " << argv[i] << endl;
exit(1);
}
}
else{
inFile.open(argv[i]);
fileCount++;
if(!inFile && fileCount==1){
cerr << "UNABLE TO OPEN " << argv[i] << endl;
exit(1);
}
else{
string line;
while(getline(inFile, line)) inputFile+=line+='\n';
if(fileCount>1){
cerr << "TOO MANY FILE NAMES" << endl;
exit(1);
}
}
}
}
int linenum = 0;
TType tt;
Token tok;
while((tok = getNextToken(&inFile, &linenum))!=DONE && tok != ERR){
tt = tok.GetTokenType();
word = tok.GetLexeme();
if(flags["-v"]==true){
(tt == ICONST||tt==SCONST||tt==IDENT) ? cout<<enumTypes[tok.GetTokenType()]<<"("<< tok.GetLexeme()<<")"<<endl : cout<< enumTypes[tok.GetTokenType()]<<endl;
}
if(flags["-mci"]==true){
if(tt==IDENT){
(identMap.find(word)!=identMap.end()) ? identMap[word]++ : identMap[word]=1;
if(identMap[word]>mostCommonCount) mostCommonCount = identMap[word];
}
}
if(flags["-sum"]==true){
numOfTokens++;
if(tt==SCONST){
numOfStrings++;
l = word.length();
if(l > maxStringLength) maxStringLength = l;
}
}
}
if(tok==ERR){
cout << "Error on line" << tok.GetLinenum()<<"("<<tok.GetLexeme()<<")"<<endl;
return 0;
}
if(flags["-mci"]==true){
cout << "Most Common Identifier: ";
if(!identMap.empty()){
word ="";
for(auto const& it : identMap){
if(it.second==mostCommonCount) word += it.first + ",";
}
word.pop_back();
cout << word << endl;
}
}
if(flags["-sum"]){
numOfLines = tok.GetLinenum();
numOfLines = tok.GetLinenum();
cout << "Total lines: " << numOfLines << endl;
cout << "Total tokens: " << numOfTokens << endl;
cout << "Total strings: " << numOfStrings << endl;
cout << "Length of longest string: " << maxStringLength << endl;
}
inFile.close();
return 0;
}
For some reason this code is running infinitely. I cannot figure out the source of error. I also do not know whether this file or the other linked file is causing this error so I posted the main program code. I think is one of the switch statements that causing this error but I am not sure. FYI: I am supposed to make a lexical analyzer so I had three files one lexigh.h (contains all the data types and all the functions), getToken.cpp(file that defines the functions from lexigh.h) and the main program which calls the methods and tests it.
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!
I am writing a C++ code to calculate the code coverage and I want to used the OpenMP to help enhance my code by minimizing the overall run time by making the functions work in parallel so I can get less run time.
Can someone please tell me how and where to use the OpenMP?
int _tmain(int argc, _TCHAR* argv[])
{
std::clock_t start;
start = std::clock();
char inputFilename[] = "Test-Case-3.cs"; // Test Case File
char outputFilename[] = "Result.txt"; // Result File
int totalNumberOfLines = 0;
int numberOfBranches = 0;
int statementsCovered = 0;
float statementCoveragePercentage = 0;
double overallRuntime = 0;
ifstream inFile; // object for reading from a file
ofstream outFile; // object for writing to a file
inFile.open(inputFilename, ios::in);
if (!inFile) {
cerr << "Can't open input file " << inputFilename << endl;
exit(1);
}
totalNumberOfLines = NoOfLines(inFile);
inFile.clear(); // reset
inFile.seekg(0, ios::beg);
numberOfBranches = NoOfBranches(inFile);
inFile.close();
statementsCovered = totalNumberOfLines - numberOfBranches;
statementCoveragePercentage = (float)statementsCovered * 100/ totalNumberOfLines;
outFile.open(outputFilename, ios::out);
if (!outFile) {
cerr << "Can't open output file " << outputFilename << endl;
exit(1);
}
outFile << "Total Number of Lines" << " : " << totalNumberOfLines << endl;
outFile << "Number of Branches" << " : " << numberOfBranches << endl;
outFile << "Statements Covered" << " : " << statementsCovered << endl;
outFile << "Statement Coverage Percentage" << " : " << statementCoveragePercentage <<"%"<< endl;
overallRuntime = (std::clock() - start) / (double)CLOCKS_PER_SEC;
outFile << "Overall Runtime" << " : " << overallRuntime << " Seconds"<< endl;
outFile.close();
}
i want to minimize the time taken to count the number of branches by allowing multiple threads to work in parallel to calculate the number faster? how can i edit the code so that i can use the open mp and here you can find my functions:bool is_only_ascii_whitespace(const std::string& str)
{
auto it = str.begin();
do {
if (it == str.end()) return true;
} while (*it >= 0 && *it <= 0x7f && std::isspace(*(it++)));
// one of these conditions will be optimized away by the compiler,
// which one depends on whether char is signed or not
return false;
}
// Function 1
int NoOfLines(ifstream& inFile)
{
//char line[1000];
string line;
int lines = 0;
while (!inFile.eof()) {
getline(inFile, line);
//cout << line << endl;
if ((line.find("//") == std::string::npos)) // Remove Comments
{
if (!is_only_ascii_whitespace(line)) // Remove Blank
{
lines++;
}
}
//cout << line << "~" <<endl;
}
return lines;
}
// Function 2
int NoOfBranches(ifstream& inFile)
{
//char line[1000];
string line;
int branches = 0;
while (!inFile.eof()) {
getline(inFile, line);
if ((line.find("if") != std::string::npos) || (line.find("else") != std::string::npos))
{
branches++;
}
}
return branches;
}
For some reason, it just won't load the mesh file. I can't tell if its because Im entering something wrong, or if I just dont have the file in the right folder. I have it in the same folder as the .exe right now, and I have it under my "source files" too (that could be wrong).
Mesh.cpp
#include "MeshTable.h"
#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
void MeshTable::ReadMesh_M(const char *filename) {
points.clear();
faces.clear();
//the Vertex id in .m file begins from 1,
//we insert an empty point to align the index
points.push_back(Point());
std::ifstream input("C:\\Users\\Zach\\Documents\\Visual Studio 2010\\Projects\\MAIN\\Release\\dog.m");
while(input.good()) {
std::string line;
getline(input, line);
if (line.empty()) {
continue;
}
std::stringstream ss(line);
std::string title;
int id;
ss >> title;
if (title == "Vertex") {
Point pt;
ss >> id >> pt[0] >> pt[1] >> pt[2];
points.push_back(pt);
}
else if (title == "Face") {
Face face;
ss >> id >> face.pt_ids[0] >> face.pt_ids[1] >> face.pt_ids[2];
faces.push_back(face);
}
}
input.close();
}
void MeshTable::SaveMesh_M(const char *filename) {
std:: ofstream output(C:\\Users\\Zach\\Documents\\Visual Studio 2010\\Projects\\MAIN\\Release\\dog_out.m);
for (unsigned int i = 1; i < points.size(); ++i) {
const Point& pt = points[i];
output << "Vertex " << i << " " << pt[0] << " " << pt[1] << " " << pt[2] << "\n";
}
for (unsigned int i = 0; i < faces.size(); ++i) {
const Face& face = faces[i];
output << "Face " << i + 1 << " " << face.pt_ids[0] << " " << face.pt_ids[1] << " " << face.pt_ids[2] << "\n";
}
output.close();
}
It builds fine, but when I try to debug it, the OpenGL window pops open for like 3 seconds and then closes and says "The program '[3188] Main.exe: Native' has exited with code -1 (0xffffffff)." Which comes from my main.cpp.
if (argc != 2) {
std::cout << "Load a .m file as a mesh table.\n";
std::cout << "Usage: " << argv[0] << " input_mesh.m\n";
exit(-1);
}
EDIT Once I deleted this, it worked. My teacher gave me this (part) of the code so I dont really understand why that would make it not work.
if (argc != 2) {
std::cout << "Load a .m file as a mesh table.\n";
std::cout << "Usage: " << argv[0] << " input_mesh.m\n";
exit(-1);
}
if (argc != 2) {
std::cout << "Load a .m file as a mesh table.\n";
std::cout << "Usage: " << argv[0] << " input_mesh.m\n";
exit(-1);
}
You need to pass name of mesh file into command line parameter when you run the program. I.e. it should be launched as "program.exe meshfile.m".
In VS 2008 debugging parameters/command line arguments could be specified in project properties->configuration properties->debugging->command arguments. In VS2010 they could be in similar locations.
Also, read "output" when you run the program. Code fragment provided by your teacher actually prints program usage.
What do I have to do to make my program use a file that has been dragged and dropped onto its icon as a parameter?
My current main method looks like this:
int main(int argc, char* argv[])
{
if (argc != 2) {
cout << "ERROR: Wrong amount of arguments!" << endl;
cout << "\n" << "Programm closed...\n\n" << endl;
exit(1);
return 0;
}
Converter a(argv[1]);
// ...
cout << "\n" << "Programm finished...\n\n" << endl;
// cin.ignore();
return 0;
}
What I'd really like to be able to do is select 10 (or so) files, drop them onto the EXE, and process them from within my application.
EDIT:
The incomming parameter is used as filename, constructed in the cunstructor.
Converter::Converter(char* file) {
// string filename is a global variable
filename = file;
myfile.open(filename.c_str(), ios_base::in);
}
The method where the textfile gets read:
string Converter::readTextFile() {
char c;
string txt = "";
if (myfile.is_open()) {
while (!myfile.eof()) {
myfile.get(c);
txt += c;
}
} else {
error("ERROR: can't open file:", filename.c_str());
}
return txt;
}
EDIT2:
deleted
Update:
I got again to this point.
Actual Main method:
// File path as argument
int main(int argc, char* argv[]) {
if (argc < 2) {
cout
<< "ERROR: Wrong amount of arguments! Give at least one argument ...\n"
<< endl;
cout << "\n" << "Programm closed...\n\n" << endl;
cin.ignore();
exit(1);
return 0;
}
vector<string> files;
for (int g = 1; g < argc; g++) {
string s = argv[g];
string filename = "";
int pos = s.find_last_of("\\", s.size());
if (pos != -1) {
filename = s.substr(pos + 1);
cout << "argv[1] " << argv[1] << endl;
cout << "\n filename: " << filename << "\n pos: " << pos << endl;
files.push_back(filename);
}
files.push_back(s);
}
for (unsigned int k = 0; k < files.size(); k++)
{
cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
Converter a(files.at(k).c_str());
a.getATCommandsFromCSV();
}
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
return 0;
}
Actually the console window apears for maybe 0.5 sec and closes again.
It doen't stop on any of my cin.ignore(); Maybe it doesn't get there?
Can anyone help?
Your program does not need to do anything special apart from handling command-line arguments. When you drag-drop a file onto an application in Explorer it does nothing more than to pass the file name as argument to the program. Likewise for multiple files.
If all you expect is a list of file names, then just iterate over all arguments, do whatever you want with them and be done. This will work for zero to almost arbitrarily many arguments.
Maybe you could write a test program like this:
int main(int argc, char* argv[])
{
// argv[0] is not interesting, since it's just your program's path.
for (int i = 1; i < argc, ++i)
cout << "argv[" << i << "] is " << argv[i] << endl;
return 0;
}
And see what happens after you throw different files at it.
EDIT: Just look at Joey's answer.
Answer to the main question
TO SEE THE ANSWER TO YOUR LAST PROBLEM SEE BOTTOM OF THIS ANSWER
All drag&dropped files are get-able as argv[orderOfTheFile] (orderOfTheFile is from 1-n),
however how does windows create that order, now that is a real mystery...
Anyway let's say I would create 26 plain text files ( *.txt ), from a.txt to z.txt on my Desktop,
now if I would drag&dropped them on my ArgsPrinter_c++.exe located directly on C:\ drive,
an output would be similar to this:
argc = 27
argv[0] = C:\ArgsPrinter_c++.exe
argv[1] = C:\Users\MyUserName\Desktop\c.txt
argv[2] = C:\Users\MyUserName\Desktop\d.txt
argv[3] = C:\Users\MyUserName\Desktop\e.txt
argv[4] = C:\Users\MyUserName\Desktop\f.txt
argv[5] = C:\Users\MyUserName\Desktop\g.txt
argv[6] = C:\Users\MyUserName\Desktop\h.txt
argv[7] = C:\Users\MyUserName\Desktop\i.txt
argv[8] = C:\Users\MyUserName\Desktop\j.txt
argv[9] = C:\Users\MyUserName\Desktop\k.txt
argv[10] = C:\Users\MyUserName\Desktop\l.txt
argv[11] = C:\Users\MyUserName\Desktop\m.txt
argv[12] = C:\Users\MyUserName\Desktop\n.txt
argv[13] = C:\Users\MyUserName\Desktop\o.txt
argv[14] = C:\Users\MyUserName\Desktop\p.txt
argv[15] = C:\Users\MyUserName\Desktop\q.txt
argv[16] = C:\Users\MyUserName\Desktop\r.txt
argv[17] = C:\Users\MyUserName\Desktop\s.txt
argv[18] = C:\Users\MyUserName\Desktop\t.txt
argv[19] = C:\Users\MyUserName\Desktop\u.txt
argv[20] = C:\Users\MyUserName\Desktop\v.txt
argv[21] = C:\Users\MyUserName\Desktop\w.txt
argv[22] = C:\Users\MyUserName\Desktop\x.txt
argv[23] = C:\Users\MyUserName\Desktop\y.txt
argv[24] = C:\Users\MyUserName\Desktop\z.txt
argv[25] = C:\Users\MyUserName\Desktop\a.txt
argv[26] = C:\Users\MyUserName\Desktop\b.txt
My ArgsPrinter_c++.exe source code:
#include <iostream>
using namespace std;
int main(int argc, char* argv[]) {
cout << "argc = " << argc << endl;
for(int i = 0; i < argc; i++)
cout << "argv[" << i << "] = " << argv[i] << endl;
std::cin.ignore();
return 0;
}
Your last problem
I have created a simple program that creates only a sceleton of your class so it can be used, and the program's main itself ran JUST FINE => if your program exits too soon, the problem will be in your class...
Tested source code:
#include <iostream>
#include <vector>
using namespace std;
class Converter{
public:
Converter(const char* f){ cout << f << endl; }
void getATCommandsFromCSV(){ cout << "called getATCommandsFromCSV" << endl; }
};
int main(int argc, char* argv[]) {
vector<string> files;
for (int g = 1; g < argc; g++) {
string s = argv[g];
string filename = "";
int pos = s.find_last_of("\\", s.size());
if (pos != -1) {
filename = s.substr(pos + 1);
cout << "argv[1] " << argv[1] << endl;
cout << "\n filename: " << filename << "\n pos: " << pos << endl;
files.push_back(filename);
}
files.push_back(s);
}
for (unsigned int k = 0; k < files.size(); k++)
{
cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
Converter a(files.at(k).c_str());
a.getATCommandsFromCSV();
}
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
return 0;
}