Hello, the compiler has a problem with my "std::string line". It's in there twice, but I didn't know how else to do it. The program is like a lexical analyzer. What's the best way to fix this?

#include <iostream>
#include <fstream>
#include <string>
#include <iostream>
#include <string>
#include <cctype> // for std::isspace(), etc.

int main(int argc, char *argv[]) {
if(argc != 2) {
std::cerr << "Usage: " << argv[0] << " input-file\n";
return 1;
}

// open file

std::ifstream input(argv[1]);
if(!input.is_open()) {
std::cerr << "Error opening file \"" << argv[1] << "\"\n";
}

std::string line;
while(std::getline(input, line)) {
std::cout << "Got line: [" << line << "]\n";
}









//search

void print_tokens(const std::string &data);


std::string line;

while(std::getline(std::cin, line)) {
print_tokens(line);
}

return 0;
}

void print_tokens(const std::string &data) {
enum {
MODE_OUTSIDE,
MODE_IN_WORD,
MODE_SYMBOL
} mode = MODE_OUTSIDE;

std::string::size_type x = 0;
while(x < data.length()) {
char c = data[x];
switch(mode) {
case MODE_OUTSIDE:
if(std::isspace(c)) {
x ++;
}
else if(std::isalnum(c)) {
mode = MODE_IN_WORD;
std::cout << '"';
}
else {
mode = MODE_SYMBOL;
}
break;
case MODE_IN_WORD:
if(std::isalnum(c)) {
std::cout << c;
x ++;
}
else {
std::cout << '"' << std::endl;
mode = MODE_OUTSIDE;
}
break;
case MODE_SYMBOL:
if(!std::isalnum(c) && !std::isspace(c)) {
std::cout << "[" << c << "]\n";
x ++;
}
else {
mode = MODE_OUTSIDE;
}
break;
}
}
}

Edited 6 Years Ago by XodoX: n/a

You should really format your code so other people can read it.

I commented in a few things that I did and do not put function prototypes within other functions.

#include <iostream>
#include <fstream>
#include <string>
#include <iostream>
#include <string>
#include <cctype> // for std::isspace(), etc.

void print_tokens(const std::string &data); //move the prototype up here (do not declare prototypes within other functions)

int main(int argc, char *argv[])
{
	if(argc != 2)
	{
		std::cerr << "Usage: " << argv[0] << " input-file\n";
		return 1;
	}

	// open file
	std::ifstream input(argv[1]);
	std::string line; //only need to declare line once

	if(!input.is_open())
	{
		std::cerr << "Error opening file \"" << argv[1] << "\"\n";
	}

	while(std::getline(input, line))
	{
		std::cout << "Got line: [" << line << "]\n";
	}

	while(std::getline(std::cin, line))
	{
		print_tokens(line);
	}

	input.close(); //close your input stream when you are done with it

	return 0;
}

void print_tokens(const std::string &data)
{
	enum
	{
		MODE_OUTSIDE,
		MODE_IN_WORD,
		MODE_SYMBOL
	} mode = MODE_OUTSIDE; //I wouldn't have nested this enum within a function but depends on if you are only going to use it for this one thing

	std::string::size_type x = 0;
	while(x < data.length())
	{
		char c = data[x];
		switch(mode)
		{
			case MODE_OUTSIDE:
				if(std::isspace(c))
				{
					x++;
				}
				else if(std::isalnum(c))
				{
					mode = MODE_IN_WORD;
					std::cout << '"';
				}
				else
				{
					mode = MODE_SYMBOL;
				}
				break;

			case MODE_IN_WORD:
				if(std::isalnum(c))
				{
					std::cout << c;
					x++;
				}
				else
				{
					std::cout << '"' << std::endl;
					mode = MODE_OUTSIDE;
				}
				break;

			case MODE_SYMBOL:
				if(!std::isalnum(c) && !std::isspace(c))
				{
					std::cout << "[" << c << "]\n";
					x++;
				}
				else
				{
					mode = MODE_OUTSIDE;
				}
				break;
		}
	}
}

Thanks a lot! Sorry, I wasn't finished yet, so I didn't worry about it yet. I'm having difficulties to add the part where it creates the output wfile with the output. How do I do this?

BTW. The code works fine so far. Thanks again.

So your print_tokens() function is supposed to output the lines to a file? I just see so much stuff wrong with the way you did it.

Edit: Can you include a sample input file so I can test it?

Edited 6 Years Ago by sfuo: n/a

Oh ma, it's that bad? Sorry, I thought I was doing ok;/

The input files look like this one:

class A {
int a[11],x,y,z;
char *oneString;
public:
A() { oneString= new char[100]; }
A() { delete oneString; }
void f();
};
void A::f() {
int temp;
x=y+1;
z=x+2; z= x*x;
}

And this one:

int sum(int a,int b) { return a+b; }
void main()
{
int i,x1,x2,r; int a[11];
for(i=1;i<=10;i++) a[i]=0;
x1=2; x2=10;
a[1]= x1*x2;
r= sum(x1,x2);
}

Edited 6 Years Ago by XodoX: n/a

This article has been dead for over six months. Start a new discussion instead.