I have an assignment that needs me to read in a file that is a source code in a .txt file. Then read in a file listing c++ keywords. Examine the first file for those keywords and convert them to lowercase and export the new file into a .cpp file.

I can read in the 2 files and generate the output file, but have come to a road block with the following

1) comparing the keywords from file2 with file1 keywords and changing the case in file1.

2) Keeping the format when exporting to the .cpp file (currently it only acknowledges words (skips the special characters).

I'm just looking for a push in the right direction (thats why I'm not including code).

thanks

Recommended Answers

All 7 Replies

I'm not sure I understand the format of the *.txt file. Will you post an example file?

And the keyword file. What does it look like -- post sample lines from that file.

main.txt (file that needs to be converted to .CPP)

#include <iostream>

using namespace std;

INT main()
{

    INT i = 0;
   VOID sample;

  FOR(j = 0; j < 10; j++);
 IF(i = 12)
{
   code;
}

RETURN 0;
}

keywords.txt

if
for
void
return
int

Basically I need the main.txt to read the words from the keyword.txt and convert the ones that are capitalized to lowercase.

I can get the main.txt to export everything to a .CPP but it loses the format structure.

I get the following instead of the above structure:

#include<iostream>#include<fstream>usingnamespacestd;.....

Member Avatar for stephen.id

umm are you saying everything is put onto one line if thats the case use "\n" or endl; to seperate each line of code

First, read all the words in keywords.txt into a string array or vector.
vector<string> keywords

  1. Then begin reading the main.txt file
  2. for each line in main.txt

    1. check each word from keywords.txt to see if any are in the line just read. If you read the line into a std::string object this will be much simpler because you can call std::string's find() method. But, since keywords are in lower-case characters and the word in main.txt will probably be in upper-case, you will have to convert the keyword to uppercase before doing the find().
    2. you can use std::string's replace() method to replace the keywords line.replace(pos, keyword[i].length(), keyword[i]
    3. Write the result out to the main.cpp file, including "\n" at the end of the line.

Ok here is what I have so far. My main concern at the moment is getting the output to maintain it's structure. I'm including both .CPP files (they aren't too long)

token.cpp (houses the functions that are being used)

#include <string.h>
#include "CToken.h"

bool isValidIdentifier(char c)
{
	//It's valid if it falls within the range below
	if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z') ||
	   (c >= 'A' && c <= 'Z') || c == '_' || c == '"' || c == '/' ||
	   c == '(' || c == ')' || c == '-' || c == '.')
	   return true;

	return false;
}

void CToken::SetTokenStream(char *data)
{
	Shutdown();

	m_length = strlen(data);
	m_data = new char [(m_length + 1) * sizeof(char)];
	strcpy(m_data, data);
	m_data[m_length] = '\0';
}

bool CToken::GetNextToken(char *buffer)
{
	bool inString = false;
	m_startIndex = m_endIndex;

	if(buffer) buffer[0] = '\0';

	while(m_startIndex < m_length && ((m_data[m_startIndex] == ' ' || m_data[m_startIndex] == '\t') || inString))
	{
		if(m_data[m_startIndex] == '"') inString = !inString;			
		m_startIndex++;
	}

	m_endIndex = m_startIndex + 1;

	if(m_startIndex < m_length)
	{
		bool valid = true;

		if(isValidIdentifier(m_data[m_startIndex]))
			while(isValidIdentifier(m_data[m_endIndex]) || m_data[m_endIndex] == '.') m_endIndex++;
		else valid = false;

		if(buffer != NULL)
		{
			if(valid)
			{
				strncpy(buffer, m_data + m_startIndex, m_endIndex - m_startIndex);
				buffer[m_endIndex - m_startIndex] = '\0';

				if(strcmp(buffer, "\n") == 0) buffer[0] = '\0';
			}
			else buffer[0] = '\0';
		}

		return true;
	}
	return false;
}

bool CToken::GetNextToken(char *token, char *buffer)
{
	char tok[256];

	while(GetNextToken(tok))
		if(stricmp(tok, token) == 0) return GetNextToken(buffer);

	return false;
}

bool CToken::MoveToNextLine(char *buffer)
{
	if(m_startIndex < m_length && m_endIndex < m_length)
	{
		m_startIndex = m_endIndex;

		while(m_endIndex < m_length && (m_data[m_endIndex] != '\n' &&
			  m_data[m_endIndex] != '\r' && m_data[m_endIndex] != '\0')) m_endIndex++;

		if(m_endIndex - m_startIndex >= 511) return false;

		if(buffer != NULL)
		{
			strncpy(buffer, m_data + m_startIndex, m_endIndex - m_startIndex);
			buffer[m_endIndex - m_startIndex] = '\0';
		}
	}
	else return false;

	return true;
}

void CToken::Shutdown()
{
	if(m_data) delete[] m_data;
	m_data = NULL;

	m_length = m_startIndex = m_endIndex = 0;
}

Main .cpp file

#include <iostream>
#include "CToken.h"

using namespace std;

int main(int arg, char **argc)
{
	//Open external file
	FILE *file = fopen("main.txt", "r+"); //opens main.txt for reading & writing
	FILE *file2 = fopen("keywords.txt", "r"); //opens keywords file for reading
	FILE *file3 = fopen("main.cpp", "w"); //creates main.cpp file

	//display errors
	if(!file)
	{
		cout << "Error reading file." <<endl <<endl;
		return 0;
	}

	//Get file length
	fseek(file, 0, SEEK_END);
	int length = ftell(file);
	fseek(file, 0, SEEK_SET);

	//Read data from file
	char *data = new char[(length + 1) * sizeof(char)];
	if(!data) return NULL;
	fread(data, length, 1, file);
	data[length] = '\0';

	//Close file
	fclose(file);
	fclose(file2);

	//set file to lexar
	CToken token;
	token.SetTokenStream(data);

	//Delete data array
	delete[] data; 
	data = NULL;

	//Get total tokens
	int totalTokens = 0;
	char buff[256] = { 0 };

	while(token.GetNextToken(buff))
		if(buff[0] != '\0') totalTokens++;


	//Display stats
	cout <<"			 File name: " << "main.txt." << endl;
	cout <<"	File size in bytes: " << length<<"." << endl;
	cout <<"Total number of tokens: " << totalTokens << "." <<endl;

	cout << endl << endl;

	cout << "Token stream:" <<endl <<endl;

	//Reset
	token.Reset();

	//Print tokens
	while(token.GetNextToken(buff))
		if(buff[0] != '\0') 
			fprintf(file3,buff);

	//Release memory
	token.Shutdown();

	cout << endl << endl << endl;

	return 0;
}

Any help getting it to output correctly would be greatly appreciated.

post CToken.h

Here is the header file for CToken

//Header file for Token

#ifndef _TOKEN_H
#define _TOKEN_H

class CToken
{
private:
	int m_length;
	int m_startIndex, m_endIndex;
	char *m_data;

public:
	CToken() : m_length(0), m_startIndex(0), m_endIndex(0), m_data(0) {}
	~CToken() { Shutdown(); }

	void Reset() {m_startIndex = m_endIndex = 0; }
	void SetTokenStream(char *data);
	void Shutdown();

	bool GetNextToken(char *buffer);
	bool GetNextToken(char *token, char *buffer);
	bool MoveToNextLine(char *buffer);
};
#endif
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.