This question already has answers here:
How to determine if a string is a number with C++?
(36 answers)
Closed 4 years ago.
I'm trying to enter the format of
"prog1 1 all file1"
the first input has to be a argv[1] should be an int.
So i need a way to determine if argv[1] is entered as a string "xxx" ( "prog1 xxx" ) it should return "NO PHRASE LENGTH" but its returning "INVALID PHRASE LENGTH".
I see there is a isdigit() function but im not sure how i would use that.
int main(int argc, char *argv[]){
try{
if(argc == 1){
cout << "NO PHRASE LENGTH" << endl; exit(1);
}
else if((stoi(argv[1])) <= 0 ){
cout << "INVALID PHRASE LENGTH" << endl; exit(1);
}
else if(argc == 2){
cout << "NO MODE" << endl; exit(1);
}
else if(!(std::string(argv[2]) == "all") && !(std::string(argv[2]) == "top")){
cout << "INVALID MODE" << endl;
}
else if(argc == 3){
cout << "NO FILES GIVEN" << endl;
}
else if(argc >= 4){
ifstream f;
for(int i = 4; i < argc; i--){
f.open( argv[i] );
if( ! f.good() ) {
cout << "BAD FILE " << argv[i] << endl; exit(1);
}
//cout << "OK" << endl;
//f.close();
}
}
else
return 0;
}
catch(exception e){
}}
Your code is quite confusing. I am not sure what you were doing with the for loop to open the file. Anyway, I have given an example of what it could be.
int main(int argc, char *argv[])
{
if(argc != 4)
{
cout << "Program requires 3 parameters!" << endl;
return -1;
}
if(std::string(argv[2]) != "all" && std::string(argv[2]) != "top")
{
cout << "INVALID MODE" << endl;
return -1;
}
try
{
if(stoi(argv[1]) < 1)
{
cout << "ZERO OR NEGATIVE PHRASE LENGTH" << endl;
return -1;
}
ifstream f(argv[3]);
if(!f)
{
cout << "BAD FILE " << argv[3] << endl;
return -1;
}
// Now do whatever you want with the opened file
}
catch(out_of_range e)
{
cout << "NON-INT PHRASE LENGTH" << endl;
return -1;
}
return 0;
}
Don't use std::endl when all you want to say is '\n' (or "...\n"). std::endl not only inserts a newline into the stream but also flushes it. If you *really* want to flush a stream be explicit and use std::flush.
Don't use exit() to end a program if there are other ways to do so. If you use exit() no stack unwinding will occur.
#include <cstdlib>
#include <string>
#include <iostream>
#include <exception>
#include <fstream>
int main(int argc, char **argv)
{
if (argc == 1) {
std::cerr << "NO PHRASE LENGTH\n";
return EXIT_FAILURE;
}
if (argc == 2) {
std::cerr << "NO MODE\n";
return EXIT_FAILURE;
}
if (argc == 3) {
std::cerr << "NO FILES GIVEN\n";
return EXIT_FAILURE;
}
int phrase_length;
try {
phrase_length = std::stoi(argv[1]);
if (phrase_length < 0)
throw std::out_of_range{ nullptr };
}
catch (std::invalid_argument) {
std::cerr << "NO PHRASE LENGTH";
return EXIT_FAILURE;
}
catch (std::out_of_range) {
std::cerr << "PHRASE LENGTH OUT OF RANGE\n";
return EXIT_FAILURE;
}
std::string mode{ argv[2] };
if ( mode != "all" && mode != "top") {
std::cerr << "INVALID MODE\n";
return EXIT_FAILURE;
}
for (int i = 3; i < argc; ++i) {
std::fstream input_file{ argv[i] };
if (!input_file.is_open()) {
std::cerr << "BAD FILE \"" << argv[i] << "\"\n";
return EXIT_FAILURE;
}
}
}
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.
So my code compiles well, but whenever I try running the program, it seg faults. I ran it through gdb and got this set of error:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct null not valid
Program received signal SIGABRT, Aborted.
0x00007ffff722bcc9 in __GI_raise (sig=sig#entry=6) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
56 ../nptl/sysdeps/unix/sysv/linux/raise.c: No such file or directory.
Here is my code if it helps:
using namespace std;
#include <iostream>
#include <vector>
#include <cmath>
#include<fstream>
#include <cstdlib>
#include <utility>
#include <string>
class Page
{
public:
int TimeStamp;
int ProgramOwner;
int LocalPageNumber;
};
//Pair: first entry is local page, second entry is global page
//Second entry: 1 if in main memory, 0 if not
class Program
{
public:
vector< pair<int,int> > MemoryMap;
};
class Memory
{
public:
vector<Program> Programs;
vector<Page> Pages;
};
void checkArguments(int argc, char *argv[]);
bool checkPageAlgorithm(char *argv[]);
bool checkPageSize(int pagesize);
bool checkPageStyle(char *argv[]);
bool checkPTrace(string ProgramTraceFile);
bool checkPList(string ProgramListFile);
int main(int argc, char *argv[])
{
//checkArguments(argc, argv);
const int MemSize = 512;
int pageSize = atoi(argv[3]);
string programListFile = argv[1];
string ProgramTraceFile = argv[2];
string pageAlgorithm = argv[4];
string pageStyle = argv[5];
int programNumber;
int programSize;
int PagesNeeded;
Memory MainMemory;
int numberFrames;
int pageFaults = 0;
int numPrograms = 0;
int PagesPerProgram;
int LocalPage;
int activeProgram;
int requestedLocation;
int newPageLocation;
bool foundInMemory;
ifstream fileIn;
fileIn.open(programListFile.c_str());
if(fileIn.fail())
{
cerr << "List file not found." << endl;
fileIn.close();
exit(1);
}
else
{
while(!fileIn.eof())
{
cout << "hey0";
fileIn >> programNumber;
fileIn >> programSize;
numPrograms++;
}
}
numberFrames = ceil(MemSize/pageSize);
PagesPerProgram = ceil(numberFrames/numPrograms);
MainMemory.Pages.resize(numberFrames);
cout << "hey1";
while(!fileIn.eof())
{
cout << "hey2";
fileIn >> programNumber;
fileIn >> programSize;
cout << "hey3";
PagesNeeded = ceil(programSize/pageSize);
for(int i = 0; i < PagesNeeded; i++)
{
LocalPage = i;
MainMemory.Pages[i].ProgramOwner = programNumber;
MainMemory.Pages[i].LocalPageNumber = LocalPage;
}
cout << "hey3";
if(PagesNeeded > PagesPerProgram)
PagesNeeded = PagesPerProgram;
for(int i = 0; i < PagesNeeded; i++)
{
MainMemory.Programs[programNumber].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
MainMemory.Programs[programNumber].MemoryMap[i].second = 1;
if(pageAlgorithm == "clock")
MainMemory.Pages[i].TimeStamp = 1;
else
MainMemory.Pages[i].TimeStamp = 0;
}
}
fileIn.close();
//LRU Algorithm Implementation
if(pageAlgorithm == "lru")
{
cout << "here1";
fileIn.open(ProgramTraceFile.c_str());
if(fileIn.fail())
{
cerr << "That file does not exist." << endl;
fileIn.close();
exit(1);
}
else
{
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
while(!fileIn.eof())
{
foundInMemory = false;
for(int i = 0; i < static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()); i++)
{
if((MainMemory.Programs[activeProgram].MemoryMap[i].second == 1) &&
(MainMemory.Programs[activeProgram].MemoryMap[i].first == newPageLocation))
foundInMemory = true;
if(foundInMemory)
break;
}
if(!foundInMemory)
{
pageFaults++;
if(static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) < PagesPerProgram)
{
pair<int, int> temp;
temp.first = newPageLocation;
temp.second = 1;
MainMemory.Programs[activeProgram].MemoryMap.push_back(temp);
}
else
{
for(int i = 0; i < (static_cast<int>(MainMemory.Programs[activeProgram].MemoryMap.size()) - 1); i++)
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = newPageLocation;
}
if(pageStyle == "1")
{
if(MainMemory.Pages[i].TimeStamp >= MainMemory.Pages[i+1].TimeStamp)
{
MainMemory.Programs[activeProgram].MemoryMap[i].first = MainMemory.Pages[i].LocalPageNumber;
}
}
MainMemory.Pages[i].TimeStamp++;
}
}
}
fileIn >> activeProgram;
fileIn >> requestedLocation;
newPageLocation = ceil(requestedLocation/pageSize);
}
}
}
cout << "------------------------------------" << endl;
cout << "Page Size: " << pageSize << endl;
cout << "Page Replacement Algorithm: " << pageAlgorithm << endl;
cout << "Paging Style: ";
if(pageStyle == "0")
cout << "Demand" << endl;
else
cout << "Prepaging" << endl;
cout << "Number of Page Faults: " << pageFaults << endl;
cout << "------------------------------------" << endl;
return 0;
}
bool checkPList(string programlistfile)
{
ifstream ListFile(programlistfile.c_str());
if(ListFile.fail())
{
cerr << "Cannot find file " << programlistfile << endl;
ListFile.close();
return false;
}
else
{
ListFile.close();
return true;
}
}
bool checkPTrace(string programTraceFile)
{
ifstream TraceFile;
TraceFile.open(programTraceFile.c_str());
if(TraceFile.fail())
{
cerr << "Cannot find file " << programTraceFile << endl;
TraceFile.close();
return false;
}
else
{
TraceFile.close();
return true;
}
}
bool checkPageStyle(string pageStyle)
{
if(pageStyle == "0")
return true;
else if(pageStyle == "1")
return true;
else
{
cerr << "Page Style can be: 0 or 1." << endl;
return false;
}
}
bool checkPageSize(int pagesize)
{
bool isValid = false;
switch(pagesize)
{
case 1:
isValid = true;
break;
case 2:
isValid = true;
break;
case 4:
isValid = true;
break;
case 8:
isValid = true;
break;
case 16:
isValid = true;
break;
default:
cerr << "Page Size can be: 1, 2, 4, 8, or 16." << endl;
isValid = false;
}
return isValid;
}
bool checkPageAlgorithm(string pageAlgorithm)
{
if(pageAlgorithm == "lru")
return true;
else if(pageAlgorithm == "fifo")
return true;
else if(pageAlgorithm == "clock")
return true;
else
{
cerr << "Valid Page Algorithms are: lru, fifo, or clock" << endl;
return false;
}
}
void checkArguments(int argc, char *argv[])
{
if(argc < 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(argc > 6)
{
cerr << "Invalid number of arguments. Should be: programlist programtrace pagesize pagealgorithm pagingstyle" << endl;
exit(1);
}
else if(!checkPageAlgorithm(argv[4]))
exit(1);
else if(!checkPageSize(atoi(argv[3])))
exit(1);
else if(!checkPageStyle(argv[5]))
exit(1);
else if(!checkPTrace(argv[2]))
exit(1);
else if(!checkPList(argv[1]))
exit(1);
return;
}
The output 'heys' are just to see if they get triggered within gdb, which they don't.
You forgot to actually ask any question.
Presumably, your question is "why does my program die with SIGABRT?"
The answer was provided by the program itself: you've tried to construct std::string from a NULL character pointer, which throws std::logic_error exception (because it's not a valid thing to do).
You may have a follow-up quesiton: "where in my program does this happen?".
You could find the answer by using GDB where command. As a first guess, you didn't invoke your program with sufficient number of arguments. For example, if you did this:
gdb ./a.out
(gdb) run
then argv[1] is NULL, and this statement:
string programListFile = argv[1];
would throw the exception you are getting.
The common solution to this problem is to insist that you do have correct number of arguments, e.g. put this:
if (argc < 6) {
std::cerr << "Not enough arguments" << std::endl;
return 1;
}
at the start of main. Or just comment the call to checkArguments() back in.
I'm a little bit confused with that, but I cant understand why one code is working and another isn't.. Seems like it's the same, but largest one cathes and error in the string with calling function "GetFileAttributes".
The first code is not working.
#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <conio.h>
using namespace std;
int _tmain(int argc, _TCHAR* argv[]) {
if (argc < 2){
char answer;
do
{
cout << "You didn't type in the path to the file. Do you want to do it now? [y/n]" << endl;
cin >> answer;
} while (!cin.fail() && answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N');
cin.clear();
if (answer == 'N' || answer == 'n'){
return 0;
}
printf("%s", "Type in the path to the file\n");
scanf("%s", (argv + 1));
}
//LPCWSTR l = (LPCWSTR) (argv+1);
DWORD d = GetFileAttributes(argv[1]);
printf("%s", "Attrbiutes for this file are\n");
if (d == INVALID_FILE_ATTRIBUTES){
printf("%s", "Invalid attributes\n");
}
if (d & FILE_ATTRIBUTE_ARCHIVE){
printf("%s", "Archive\n");
}
if (d & FILE_ATTRIBUTE_COMPRESSED){
printf("%s", "Compressed\n");
}
if (d & FILE_ATTRIBUTE_DIRECTORY){
printf("%s", "Directory\n");
}
if (d & FILE_ATTRIBUTE_HIDDEN){
printf("%s", "Hidden\n");
}
if (d & FILE_ATTRIBUTE_READONLY){
printf("%s", "Read-only\n");
}
_getch();
return 0;
}
Here is the working one
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <conio.h>
int _tmain(int argc, _TCHAR* argv[])
{
DWORD x = GetFileAttributes(argv[1]);
if (x == INVALID_FILE_ATTRIBUTES)
{
std::cout << "error" << std::endl;
return 0;
}
if (x & FILE_ATTRIBUTE_ARCHIVE)
{
std::cout << "archive" << std::endl;
}
if (x & FILE_ATTRIBUTE_HIDDEN)
{
std::cout << "hidden" << std::endl;
}
if (x & FILE_ATTRIBUTE_READONLY)
{
std::cout << "read only" << std::endl;
}
if (x & FILE_ATTRIBUTE_SYSTEM)
{
std::cout << "system" << std::endl;
}
if (x & FILE_ATTRIBUTE_TEMPORARY)
{
std::cout << "temporary" << std::endl;
}
_getch();
return 0;
}
This is not the right way to use argv. DO NOT MODIFY IT. Treat it as read-only. Use a separate variable to hold the filename, prompting the user to populate that variable if needed, and then use the variable instead of argv when using the filename.
Also, new OS version introduce new file attributes, which you are not taking into account. You should output all attributes, even ones you do not recognize.
Also, you should stop mixing C and C++ I/O. Pick one or the other and be consistent with it.
Try something more like this:
#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
int _tmain(int argc, _TCHAR* argv[])
{
std::string filename;
char ch;
if (argc >= 2)
{
filename = argv[1];
}
else
{
do
{
std::cout << "You didn't provide a path to the file. Do you want to type it now? [y/n]" << std::endl;
if (!(std::cin >> ch))
return 0;
}
while ((ch != 'y') && (ch != 'Y') && (ch != 'n') && (ch != 'N'));
if ((ch == 'N') || (ch == 'n'))
return 0;
cin.clear();
do
{
std::cout << "Type in the path to the file" << std::endl;
if (!std::getline(std::cin, filename))
return 0;
}
while (filename.empty());
}
DWORD d = GetFileAttributesA(filename.c_str());
std::cout << "Attributes for file: " << filename << std::endl;
if (d == INVALID_FILE_ATTRIBUTES)
{
std::cout << "Invalid attributes" << std::endl;
}
else
{
if (d & FILE_ATTRIBUTE_ARCHIVE)
{
std::cout << "Archive" << std::endl;
d &= ~FILE_ATTRIBUTE_ARCHIVE;
}
if (d & FILE_ATTRIBUTE_COMPRESSED)
{
std::cout << "Compressed" << std::endl;
d &= ~FILE_ATTRIBUTE_COMPRESSED;
}
if (d & FILE_ATTRIBUTE_DIRECTORY)
{
std::cout << "Directory" << std::endl;
d &= ~FILE_ATTRIBUTE_DIRECTORY;
}
if (d & FILE_ATTRIBUTE_HIDDEN)
{
std::cout << "Hidden" << std::endl;
d &= ~FILE_ATTRIBUTE_HIDDEN;
}
if (d & FILE_ATTRIBUTE_READONLY)
{
std::cout << "Read-only" << std::endl;
d &= ~FILE_ATTRIBUTE_READONLY;
}
if (d != 0)
{
std::cout << "Other: " << std::hex << std::showbase << std::setw(8) << std::setfill('0') << d << std::endl;
}
}
std::cout << "Press a key to exit" << std::endl;
std::cin >> ch;
return 0;
}
Ok I did some research and I couldn't turn up anything useful. I am trying to write a program that will receive input from iwconfig (on a linux machine). It will then sort through the input, do some calculations and output to a database. Sorting through the input and outputting isn't an issue (or so I really hope it not to be) but what I am struggling with is reading input from another command line program. What I have right now as a base Hello World program is:
#include <iostream>
#include <cstdlib>
using namespace std;
int main() {
int numbr = 0;
cout << "Hello world!" << endl;
cin >> numbr;
cout << "number is " << numbr;
cout << system("iwconfig");
return 0;
}
However upon running the program, all it does is output hello world, ask for my random input and output it again. It does not output iwconfig (I also ran the line as just system("iwconfig"); without the output statement). Would someone be kind enough to explain how I could run a program like iwconfig and capture it's output?
"Would someone be kind enough to explain how I could run a program like iwconfig and capture it's output?"
Check the int system( const char *command ); documentation. It certainly doesn't provide to return the value, you want to output with your cout statement.
You probably want to have pipes established between your main and the iwconfig program, as described here, to control the input and output streams used by the child process.
To replicate the mentioned answer adapted:
int main() {
int fd_p2c[2], fd_c2p[2], bytes_read;
pid_t childpid;
char readbuffer[80];
string program_name = "iwconfig";
string receive_output = "";
if (pipe(fd_p2c) != 0 || pipe(fd_c2p) != 0) {
cerr << "Failed to pipe\n";
exit(1);
}
childpid = fork();
if (childpid < 0) {
cout << "Fork failed" << endl;
exit(-1);
}
else if (childpid == 0) {
if (dup2(fd_p2c[0], 0) != 0 ||
close(fd_p2c[0]) != 0 ||
close(fd_p2c[1]) != 0) {
cerr << "Child: failed to set up standard input\n";
exit(1);
}
if (dup2(fd_c2p[1], 1) != 1 ||
close(fd_c2p[1]) != 0 ||
close(fd_c2p[0]) != 0) {
cerr << "Child: failed to set up standard output\n";
exit(1);
}
execl(program_name.c_str(), program_name.c_str(), (char *) 0);
cerr << "Failed to execute " << program_name << endl;
exit(1);
}
else {
close(fd_p2c[0]);
close(fd_c2p[1]);
cout << "Writing to child: <<" << gulp_command << ">>" << endl;
int nbytes = gulp_command.length();
if (write(fd_p2c[1], gulp_command.c_str(), nbytes) != nbytes) {
cerr << "Parent: short write to child\n";
exit(1);
}
close(fd_p2c[1]);
while (1) {
bytes_read = read(fd_c2p[0], readbuffer, sizeof(readbuffer)-1);
if (bytes_read <= 0) break;
readbuffer[bytes_read] = '\0';
receive_output += readbuffer;
}
close(fd_c2p[0]);
cout << "From child: <<" << receive_output << ">>" << endl;
}
return 0;
}
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.