GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 08-Mar-2004, 10:34
CronoX CronoX is offline
New Member
 
Join Date: Mar 2004
Posts: 26
CronoX is on a distinguished road

C++ file I/O


Hello i wa swondering could anyone help me out. I'm new to file I/O and im trying to read in a file name given by the user with some names in it do various things to it and print it out to the screen. My problem is the file gets read but it only prints out a single chracter at a time. So if my file had

SOME
THING
IS
IN
THE
FILE
I would want that printed to the screen however it prints

S
O
M
E

T
H
I
N
G

and so on. This is the way I read in the file.
CPP / C++ / C Code:
void main ()
{
	char ch;
	 
	int temp = 1;
	
// To read in the q to quit 
	char quit[] = "q";


// Stores the name of the file 
	char fname[20];
	struct Structure *lp;

// Prompts for filename 

	cout << "Enter file name or press q to quit. \n" ;
	cin >> fname; 
	
	temp = strcmp(fname,quit);
	

	while(temp != 0)
	{
		int token = 0;
		int cur = 0; 
		int size = 0;

		FILE *fpoint;
		fpoint = fopen(fname, "r");

		if (fpoint == NULL)
			cout <<" Invalid file name \n" ; 
	
		else 
		{
			while ((ch=getc(fpoint)) != EOF)

			{
				array1[size] = ch;
				size++;
			}

			array1[size+1] = NULL; 

     
/ Function call
for (int j=0; j<= size; j++)
{
write();

}
		

			
				

	

// Prompts for filename again  

	cout << "Enter file name or press q to quit. \n" ;
	cin >> fname; 
	
	temp = strcmp(fname,quit);

	
	}
	
} 
The write function I have is giving me all kinds of problems so I was checking can anyone suggest a write function I can use to help me out. Thanks.
Last edited by dsmith : 08-Mar-2004 at 10:58. Reason: Fixed C-syntax highlighting
  #2  
Old 08-Mar-2004, 11:00
dsmith's Avatar
dsmith dsmith is offline
Senior Member
 
Join Date: Jan 2004
Location: Utah, USA
Posts: 1,351
dsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of light
Hi Cronox. Welcome to GIDForums. I have moved your post into the C/C++ help forum as the other forum is restricted for posting tutorials or coding samples and is not for asking for help with a program. I also enclosed the code with the bbcode flags to c-syntax highlight it. It really helps with the readability. See the sticky post at the top of this forum for more details.

Thanks,
d
  #3  
Old 08-Mar-2004, 17:11
WaltP's Avatar
WaltP WaltP is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Midwest US
Posts: 3,373
WaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to allWaltP is a name known to all
I seen no definition for array1 so I don't know how big it is.
I see no write() function, so can't tell if there's a probelm there either.

It looks like your input routine works correctly the way you have it written, but what you wrote may not be what you want. Do you in fact want the entire file in one big buffer or each line in separate buffers?
  #4  
Old 08-Mar-2004, 17:20
CronoX CronoX is offline
New Member
 
Join Date: Mar 2004
Posts: 26
CronoX is on a distinguished road
for array1 i have it at 2000

I wanna read the lines in seperate buffers. The write function is what I'm having problems with Right now i have it as a big switch statement where each case outputs certain words if something is read so if the file has..


int thing = 1
I would get
INT
ID (an identifier for thing)
EQ (for the equal symbol
NUM (for 1)


I'm trying to ensure its reading the line correctly so I need to read int by itself then thing by itself and so on.
  #5  
Old 08-Mar-2004, 18:27
CronoX CronoX is offline
New Member
 
Join Date: Mar 2004
Posts: 26
CronoX is on a distinguished road
As we have seen im new at this and In response to some requests Im gonna put the rest of the code in here and explain what im trying to do. I'm trying to implement a lexical analyzer and given a file containing info like

Program
{
int in1 =5;
}

My program would give
PROG
LBRACKET (For the { )
INT
IDEN (identifier in1)
EQ (for =)
NUM (for 5)
SEMMICOLON
RBRACKET

the full code im using

CPP / C++ / C Code:



#define PLUS 1
#define MINUS 2
#define TIMES 3
#define SLASH 4
#define DIV 5
#define MOD 6
#define NEG 7
#define EQ 8 
#define NE 9
#define LT 10
#define GT 11
#define LE 12
#define GE 13
#define LPAREN 14
#define RPAREN 15
#define LBRACKET 16
#define RBRACKET 17
#define LBRACE 18
#define RBRACE 19
#define SQUOTE 20
#define DQUOTE 21
#define COMMA 22
#define SEMICOLON 23
#define PERIOD 24
#define ASSIGN 25
#define AND 26
#define ARRAY 27
#define BEGIN 28
#define CHAR 29
#define CONST 30
#define ELSE 31
#define END 32
#define GET 33
#define IF 34
#define INT 35
#define NOT 36
#define OF 37
#define OR 38
#define PROC 39
#define PROG 40
#define PUT 41
#define REAL 42
#define REC 43
#define THEN 44
#define VAR 45
#define WHILE 46
#define ID 49
#define VOID 48
#define ICONST 49
#define COLON 47
#define FCONST 51
#define SCONST 51

char array1[2000];		  
int cur = 0;			//current position
int token;				//token variable 
int i = 0;			//vector position 
int getToken();			//Declares the get token function
void writeToken(int);	//Declares the write token function
string tempString;		//temp string 
char tokenArray[20];	//Array that stores tokens 


void main ()
{
	char ch;
	 
	int temp = 1;
	
// To read in the q to quit 
	char quit[] = "q";


// Stores the name of the file 
	char fname[20];
	struct Structure *lp;

// Prompts for filename 

	cout << "Enter file name or press q to quit. \n" ;
	cin >> fname; 
	
	temp = strcmp(fname,quit);
	

	while(temp != 0)
	{
		int token = 0;
		int cur = 0; 
		int size = 0;

		FILE *fpoint;
		fpoint = fopen(fname, "r");

		if (fpoint == NULL)
			cout <<" Invalid file name \n" ; 
	
		else 
		{
			while ((ch=getc(fpoint)) != EOF)

			{
				array1[size] = ch;
				size++;
			}

			array1[size+1] = NULL; 

// Displays table heading 
			cout << "Description         " << "Token     " << "Token Number     \n";
		
			for (int j=0; j<= size; j++)
			{
				
				writeToken(token);
			
			
			}
		

			
				

		}

	

// Prompts for filename again  

	cout << "Enter file name or press q to quit. \n" ;
	cin >> fname; 
	
	temp = strcmp(fname,quit);
	
		

		
	}
	
}













int getToken()

{
	int count = 0;
	
const string Num = "01234567879";

	

int cur2 = int(array1[cur]);

char tokStrings[20];

if (array1[cur] == NULL)
{
	return -20;
}


// Handles whitespace

while ((cur2 == 32) || ((cur2 >= 8) && (cur2 <=13)))
{
	cur++;
	cur2 = int(array1[cur]);
}

// Checks to find the end of the file 

if (array1[cur] == NULL)

	return -20;

//Looks for end of program 

if (array1[cur] == NULL)
	return -20;


//Ensures token begins with a letter.
	
	if(isalpha(array1[cur]))
	{

		while(isalnum(array1[cur]) || (array1[cur] == '_'))
			{
				tokStrings[count] = array1[cur];
				count++;
				cur++;

			
			
			//cout << "Unrecognized symbol \t";
			}

	}

	tokStrings[count] = NULL;

//Temporary string for token words
	
	 tempString = tokStrings; 





// If functions for the tokens that are keywords and what will be return for them in the output file. 
	
	if(tempString == "void")
	{
		return VOID;
	}
	if(tempString == "and")
	{
		return AND;
	}
		
	if(tempString == "array")
	{
		return ARRAY;
	}

	if(tempString == "begin")
	{
		return BEGIN;
	}

	if(tempString == "char")
	{
		return CHAR;
	}

	if(tempString == "const")
	{
		return CONST;
	}

	if(tempString == "else")
	{
		return ELSE;
	}
	
	if(tempString == "end")
	{
		return END;
	}

	if(tempString == "get")
	{
		return GET;
	}

	if(tempString == "if")
	{
		return IF;
	}

	if(tempString == "integer")
	{
		return INT;
	}

	if(tempString == "not")
	{
		return NOT;
	}

	if(tempString == "of")
	{
		return OF;
	}

	if(tempString == "or")
	{
		return OR;
	}

	if(tempString == "procedure")
	{
		return PROC;
	}

	if(tempString == "program")
	{
		return PROG;
	}

	if(tempString == "put")
	{
		return PUT;
	}

	if(tempString == "real")
	{
		return REAL;
	}

	if(tempString == "record")
	{
		return REC;
	}

	if(tempString == "then")
	{
		return THEN;
	}

	if(tempString == "var")
	{
		return VAR;
	}

	if(tempString == "while")
	{
		return WHILE;
	}


	
	if(tempString == "Void")
	{
		return VOID;
	}

	// For everything else not defind in above statements label it as an identifier
	else 
	{
		return ID;
	}


// Locate position number 


	if(Num.find(array1[cur]) != string::npos)
	{
		while(Num.find(array1[cur]) != string::npos)
			cur++;

		if(array1[cur] =='.') //if statement of number is a float with decimal 
		{
			cur++;
			while(Num.find(array1[cur]) != string::npos)
				cur++;
				return FCONST; //flaot constant
		}

		else 
			return ICONST; //integer constant 
	}
	
//Handles single operators 
switch(array1[cur])
{
case '+' :
	cur++;
	return PLUS;
	break;


case '-' :
	cur++;
	return MINUS;
	break;

	case '*' :
	cur++;
	return TIMES;
	break;

	case '/' :
	cur++;
	return SLASH;
	break;

	case '%' :
	cur++;
	return DIV;
	break;

	case '#' :
	cur++;
	return MOD;
	break;

	case '?' :
	cur++;
	return NEG;
	break;

	case '=' :
	cur++;
	return EQ;
	break;

	case '<' :
	cur++;
	return LT;
	break;

	case '>' :
	cur++;
	return GT;
	break;

	case '(' :
	cur++;
	return LPAREN;
	break;

	case ')' :
	cur++;
	return RPAREN;
	break;

	case '[' :
	cur++;
	return LBRACKET;
	break;

	case ']' :
	cur++;
	return RBRACKET;
	break;

	case '{' :
	cur++;
	return LBRACE;
	break;

	case '}' :
	cur++;
	return RBRACE;
	break;

	case '"' :
	cur++;
	return DQUOTE;
	break;

	case ',' :
	cur++;
	return COMMA;
	break;

	case ':' :
	cur++;
	return SEMICOLON;
	break;

	case '.' :
	cur++;
	return PERIOD;
	break;

	case '$' :
	cur++;
	return ASSIGN;
	break;




}

	
// Takes care of periods before numbers 

if((array1[cur] == '.') && (Num.find(array1[cur]) != string::npos))
{
	cur++;
	
	while(Num.find(array1[cur]) != string::npos)
		cur++;
	
	return FCONST;
}

// Case if it finds a period

else if (array1[cur] == '.')
{
	cur++;
	return PERIOD;
}

// Case if a string constant is found. 

if (array1[cur] == '\"')
{
	cur++;
	
	while ((array1[cur] != '\"') && (array1[cur] != NULL))
	{
		cur++;
	}

	cur++;
	return SCONST;
}


// Handles subtraction

if ((array1[cur] == '-') && (array1[cur+1] == '='))
{
	cur +=2;
	return MINUS;
}


else if (array1[cur] == '-') 
{
	cur ++;
	return MINUS;
}

// Handles addition

if ((array1[cur] == '+') && (array1[cur+1] == '='))
{
	cur +=2;
	return PLUS;
}


else if (array1[cur] == '+') 
{
	cur ++;
	return PLUS;
}

// Handles Multiplication 

if ((array1[cur] == '*') && (array1[cur+1] == '='))
{
	cur +=2;
	return TIMES;
}


else if (array1[cur] == '*') 
{
	cur ++;
	return TIMES;
}

// Handles Division 
if ((array1[cur] == '/') && (array1[cur+1] == '='))
{
	cur +=2;
	return SLASH;
}


else if (array1[cur] == '/') 
{
	cur ++;
	return SLASH;
}

//Handles Modulus 

if ((array1[cur] == '%') && (array1[cur+1] == '='))
{
	cur +=2;
	return MOD;
}


else if (array1[cur] == '%') 
{
	cur ++;
	return MOD;
}

// Handles Unary minus 

if ((array1[cur] == '?') && (array1[cur+1] == '='))
{
	cur +=2;
	return NEG;
}


else if (array1[cur] == '?') 
{
	cur ++;
	return NEG;
}

//Handles less than of equal to 

if ((array1[cur] == '<') && (array1[cur+1] == '='))
{
	cur +=2;
	return LE;
}


// Handles greater than or equal to 

if ((array1[cur] == '>') && (array1[cur+1] == '='))
{
	cur +=2;
	return GE;
}

// handles inequvalence 
if ((array1[cur] == '<') && (array1[cur+1] == '>'))
{
	cur +=2;
	return NE;
}

// Here im checking to see if symbols are recognized by returning zero

return 0;




}

//Write token function to write output of constants.   
void writeToken(int token)

{
	switch (token)
	{
	
	
	
		case 0 :
		cout << " Unknown Symbol \n" <<array1[cur]<< endl;
		cur++;
		break;

	
	case PLUS:
		cout << "PLUS \n";
		break;
	
	case MINUS:
		cout << "MINUS \n";
		break;
	
	case TIMES:
		cout << "TIMES \n";
		break;
	case SLASH:
		cout << "SLASH \n";
		break;
	case DIV:
		cout << "DIV \n";
		break;
	case MOD:
		cout << "MOD \n";
		break;
	case NEG:
		cout << "NEG \n";
		break;
	case EQ:
		cout << "EQ \n";
		break;
	case LT:
		cout << "LT \n";
		break;
	case GT:
		cout << "GT \n";
		break;
	case LE:
		cout << "LE \n";
		break;
	case GE:
		cout << "GE \n";
		break;
	case LPAREN:
		cout << "LPAREN  \n";
		break;
	case RPAREN:
		cout << "RPAREN \n";
		break;
	case LBRACKET:
		cout << "LBRACKET \n";
		break;
	case RBRACKET:
		cout << "RBRACKET \n";
		break;
	case LBRACE:
		cout << "RBRACE \n";
		break;
	case DQUOTE:
		cout << "DQUOTE \n";
		break;
	case COMMA:
		cout << "COMMA \n";
		break;
	case SEMICOLON:
		cout << "SEMICOLON \n";
		break;
	case PERIOD:
		cout << "PERIOD \n";
		break;
	case ASSIGN:
		cout << "ASSIGN \n";
		break;
	case AND:
		cout << "AND \n";
		break;
	case ARRAY:
		cout << "ARRAY \n";
		break;
	case BEGIN:
		cout << "BEGIN \n";
		break;
	case CHAR:
		cout << "CHAR \n";
		break;
	case CONST:
		cout << "CONST \n";
		break;
	case ELSE:
		cout << "ELSE \n";
		break;
	case END:
		cout << "END \n";
		break;
	case GET:
		cout << "GET \n";
		break;
	case IF:
		cout << "IF \n";
		break;
	case INT:
		cout << "INT \n";
		break;
	case NOT:
		cout << "NOT \n";
		break;
	case OF:
		cout << "OF \n";
		break;
	case OR:
		cout << "OR \n";
		break;
	case PROC:
		cout << "PROC \n";
		break;
	case PROG:
		cout << "PROG \n";
		break;
	case PUT:
		cout << "PUT \n";
		break;
	case REAL:
		cout << "REAL \n";
		break;
	case REC:
		cout << "REC \n";
		break;
	case THEN:
		cout << "THEN \n";
		break;
	case VAR:
		cout << "VAR \n";
		break;
	case WHILE:
		cout << "WHILE \n";
		break;

	
	
	}


}
{
If it did not show up in the correct tags sorry im still tryin gto get that down.
Last edited by dsmith : 08-Mar-2004 at 18:33. Reason: Use [c] & [/c] for c syntax highlighting
  #6  
Old 08-Mar-2004, 18:53
dsmith's Avatar
dsmith dsmith is offline
Senior Member
 
Join Date: Jan 2004
Location: Utah, USA
Posts: 1,351
dsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of light
Hi Cronox. Enclose your code in [c] and [/c] tags to highlight C code properly.

This is a pretty complex problem and I think your approach of just trying to read a file and verifying that it is read correctly as a first step is what I would do.

First I don't see any reason why you are reading this char by char and storing it into a big buffer.

I think I would do a loop like this:
  • Read a line
  • Do a debug check by writing the line to the screen
  • Check for tokens in the line
  • loop

I would recommend using the fgets statement and only processing one line at a time. This way your program can read in *any* size of file (right now it is limited to 2k) and only has to have storage for a single line.

Your program also uses quite a few global variables. I am not going to say that you should never use a global variable, but they should be the exception, not the rule.

Once a line is read in, I would pass it to another function that would split out a "token" (not identify it) and pass this token to another function that would identify it. It would do this until it reached '\n' or '\r'
or NULL.

I think if you break this down into several steps it may be easier.
  #7  
Old 08-Mar-2004, 18:57
CronoX CronoX is offline
New Member
 
Join Date: Mar 2004
Posts: 26
CronoX is on a distinguished road
Ok so i've never used an fget before would you be able to tell from the code whether it would require I make grand changes in my read or write functions or would I only need to make small changes. Thanks again for the help.
  #8  
Old 08-Mar-2004, 19:14
dsmith's Avatar
dsmith dsmith is offline
Senior Member
 
Join Date: Jan 2004
Location: Utah, USA
Posts: 1,351
dsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of light
Quote:
Originally Posted by CronoX
Ok so i've never used an fget before would you be able to tell from the code whether it would require I make grand changes in my read or write functions or would I only need to make small changes. Thanks again for the help.

Adding an fgets would not make great changes to your code in general, but it also probably is not going to help greatly with your current problems. It *should* help to simplify your code though.

You main read loop would be
CPP / C++ / C Code:
while (fgets(read_string,MAX_SIZE,fpoint) ){
  printf("Read: %s\n",read_string);  //or the cin equivalent - only for checking
  split_string(read_string);    //or whatever your processing function is
      }

This would require a #define of MAX_SIZE (probably about 200) and in the main function define read_string as:
CPP / C++ / C Code:
char read_string[MAX_SIZE];

For a description of fgets see this post.

Once you are sure that the string is being read correctly, then go on and try to parse the string for the tokens.
  #9  
Old 08-Mar-2004, 19:37
CronoX CronoX is offline
New Member
 
Join Date: Mar 2004
Posts: 26
CronoX is on a distinguished road
So after a look over after that post with the fget info. Would I have to include something like fput into my writeToken function or if I successfully get it to read the file does it look like it would output with my current write function

Thanks again.
  #10  
Old 08-Mar-2004, 20:21
dsmith's Avatar
dsmith dsmith is offline
Senior Member
 
Join Date: Jan 2004
Location: Utah, USA
Posts: 1,351
dsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of lightdsmith is a glorious beacon of light
No, I think all your writeToken function does is output the token to the screen. Fputs would put it out to a file. Is this what you wanted to do?

Also, if you want to shorten your write routine you could place all of your token strings into a static array like:
CPP / C++ / C Code:
char* token_string[]={
  "Unkown Symbol",
  "Plus",
  "Minus",
  ...
  "While"
};
Then your writeToken could simply be:

CPP / C++ / C Code:
void writeToken(int token)
{
 
    cout << token_string[token]<< endl;
}

Takes a bit to set up, but can simplify your code.
 
 

Recent GIDBlogProblems with the Navy (Officers) by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
CD burner wont burn!! robertli55 Computer Hardware Forum 1 18-Jun-2004 10:53
Yet another CD burner problem: Lite-On LSC-24082K Erwin Computer Hardware Forum 1 22-May-2004 11:28
[Tutorial] Standard I/O aaroncohn C Programming Language 20 27-Feb-2004 21:07
read specified range of lines from file etron C Programming Language 8 18-Feb-2004 08:04
How Do i get php to find out the file type of a file for me? viperman95833 MySQL / PHP Forum 2 08-Mar-2003 09:48

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 06:25.


vBulletin, Copyright © 2000 - 2010, Jelsoft Enterprises Ltd.