Hello

I'm doing my project in C++ now.

It's a Student Report Card Generator.

So here's what I plan on doing:

The file structure:

ROOT///
--> Report.exe
--> System Files
-------> License.dat
-------> ReadMe.txt
--> Reports
-------> Report 1
-------> Report 2
.
.


So, when the program is run, it looks in for License.dat file, and if found, it looks for its content and compares it with a string I have in a variable. If matched, loads the main menu, else exit.

Now, the problem is that I don't know how to make the file paths flexible. I mean, by default all files of C++ are saves in the TC folder in C:/. But if the user places the folder on desktop, how do I make sure that the program looks in it's own folder?

Another thing, how do I make a kind of a bar on the program, like split the screen so that the top portion will always contain the name of the program, and the bottom one does all the work I want.

I have looked at the window() function, but it doesn't seem to work fine. When I use clrscr(), the whole screen is gone (not the lower window), and clrwindow() doesn't seem to work. Asks for prototype.

Here's what I've one so far:

/*
 Program To Haunt Students 
 Report Card Generator
 By: Karan Goel
*/


//START HEADER FILES//
#include<iostream.h>
#include<conio.h>
#include<fstream.h>
#include<process.h>
#include<dos.h>
#include<direct.h>
//END HEADER FILES//

//START CLASS AND DECLARATION//
class report
{
public:
	void mainmenu();
	void generate();
	void del();
	void view();
	void readme();
	void close();
}r;

void report::mainmenu()
{
cout<<"\n\t\t###############################";
cout<<"\n\t\t##\tÄÅÅ MAIN MENU ÅÅÄ";
cout<<"\n\t\t##";
cout<<"\n\t\t## 1. Generate a new report";
cout<<"\n\t\t## 2. Delete an existing report";
cout<<"\n\t\t## 3. View an existing report";
cout<<"\n\t\t## 4. How to use (Read Me)";
cout<<"\n\t\t## 5. Exit";
cout<<"\n\t\t##";
cout<<"\n\t\t###############################";
}

void report::generate()
{}

void report::readme()
{}

void report::view()
{}

void report::del()
{}

void report::close()
{
cout<<"Exiting...";
delay(3000);
exit(1);
}
//END CLASS AND DECLARATION//


//START MAIN//
void main()
{
clrscr();
window(5,5,0,10);
textcolor(BLACK);
textbackground(WHITE);
cout<<"Report Generation\n";

int choice;

window(10,10,40,11);
r.mainmenu();
cout<<"\n\nEnter an input";
cin>>choice;

clrwindow();

switch(choice)
{
	case 1: r.generate();
		break;
	case 2: r.del();
		break;
	case 3: r.view();
		break;
	case 4: r.readme();
		break;
	case 5: r.close();
		break;
	default: cout<<"No valid Input found";
		break;
}

getch();
}
//END MAIN//

Please help me, and guide me.

I'll post more questions as I move forward.

Thanks a lot.

Karan


PS: I have both TC 3.0, and TC 4.5.

Recommended Answers

All 45 Replies

I know TC3 and TC4 came with very good manuals. Look up the commands in question to see what you are doing wrong.

But I have no idea which commands to use.

Help please.., I have very less time to code this thing.

argv[0] passed into your main is the path to the executable. It might be a fully-qualified path, or it might be relative to the directory the user was in when he/she started the program. If the latter, there should be a function call out to the OS to return the "current working directory" (might look something like cwd() or pwd()) or you may be able to get it from the set of environment variables managed by the shell, with a function like getenv().

As far as how to get the window text to stay where you want it to stay, and scroll (or whatever) where you want, you may have to code that yourself. I'm not a TC user at all, those functions are not part of the C++ standard.

Also, I appreciate how frustrating it can be when deadlines approach and the coding process isn't going as well as I'd like. However, your deadline is not an emergency for -us-, and with any luck, you'll learn from it how to schedule your own future programming efforts. That's a skill which comes, as far as I know, only from experience. And after 20+ years of professional software development experience, it -still- bites me once in a while.

argv[0] passed into your main is the path to the executable. It might be a fully-qualified path, or it might be relative to the directory the user was in when he/she started the program. If the latter, there should be a function call out to the OS to return the "current working directory" (might look something like cwd() or pwd()) or you may be able to get it from the set of environment variables managed by the shell, with a function like getenv().

As far as how to get the window text to stay where you want it to stay, and scroll (or whatever) where you want, you may have to code that yourself. I'm not a TC user at all, those functions are not part of the C++ standard.

Also, I appreciate how frustrating it can be when deadlines approach and the coding process isn't going as well as I'd like. However, your deadline is not an emergency for -us-, and with any luck, you'll learn from it how to schedule your own future programming efforts. That's a skill which comes, as far as I know, only from experience. And after 20+ years of professional software development experience, it -still- bites me once in a while.

Hi

Thanks for your help. I'll look at those methods.

Karan

c++ doesn't support argv[0].

c++ doesn't support argv[0].

That shouldn't be the case, even for Turbo C++. Can you post a) the error message you're getting, and b) the main() function you're using.

In order to use the command-line arguments, you need to define the arguments in the main() function declaration, like so:

int main(int argc, char* argv[])
{
    // main function goes here

    return 0;
}

The argc argument holds the number of arguments passed to the program, while argv[] is an array of C-style strings which holds the separate arguments.


Note the use of the int return type for main() . This is actually the correct, standard return value, and according to Stroustrup, the C++ standard never allowed for void main() in compliant code. Just be aware of this for the future.

I have no idea how to use

int main(int argc, char* argv[])

to extract the directory path.

I simply looked in the help and couldn't find it.

My main() is in the first OP.

Please tell me how do I put the current program directory path in a stricg so I can use it/print it.

replace

void main()
{
    ...
}

with

int main(int argc, char *argv[])
{
    cout << "Program is called: " << argv[0] << endl;
    ...
    return 0;
}

I realize that you may not have a choice in this, but I would recommend upgrading to a newer compiler if you can. Turbo C++ 4.5 is now over 15 years old, and it is still primarily a DOS compiler if I recall correctly. I'm not sure if it will work with Windows 7 at all (I know that older versions of Turbo C++ do not). More importantly, it is based on an earlier version of the C++ language, and does not work correctly with the current header files, and the current namespace system.

There are several good, freely available compilers and IDEs, such as Code::Blocks (which is based on the well-known GCC compiler) or Visual C++ Express. Not only are these modern, Windows-based compilers and IDEs, both support a version of the _getcwd() function (not a C++ standard function, it is system-dependent, but both have libraries containing it), which is exactly what you are looking for.

Ok.

So I tried argc and it prints only the exe name.

I tried to strcpy argv into another string but I get a type mismatch.

Any help on how to copy the file path to a new string?

Thanks

argc is an integer, it's the number of arguments in argv , which is an array of C-style strings. Try:

for (int i = 0; i < argc; i++ )
    cout << "arg " << i << ": " << argv[i] << endl;

As far as type-mismatch, the type of argv is const char* [] , an array of constant C-style strings. The type of one of them, for example argv[0], is just const char * . To copy a C-style string conveniently, use char * copy = strdup(argv[0]); . To be more C++-ish, simply create a STL string from it: std::string copy(argv[0]); . Note in the second case that one form of the string constructor allows you to pass a C-style string. Awesome!

Very frankly, I could not understand even a bit of what you said. :(

Can you give me the code to copy the directory path of the program into a string?

That would be a lot helpful. :)

I gave you TWO ways of copying the directory path of the program into a string. If you don't understand what I said, I recommend you stop begging for handouts and actually re-read what I said until you -do- understand it. If you still can't understand, I recommend going WAY back to really basic beginning programming. You're not going to acquire programming skills if you just get other people to do it for you.

Meanwhile, just to get you to ask a different question, here is a complete working program that does what you asked, and proves that it did it by printing it out.

#include <iostream>
#include <string>

int main (int argc, char *argv[])
{
    if (argc < 1) {
        std::cerr << "ERROR: program has zero arguments, "
                  << "cannot extract program-name" << std::endl;
        return 1;
    }

    std::string program_name (argv[0]);
    std::cout << "Program name is: " << program_name << std::endl;
    return 0;
}

I gave you TWO ways of copying the directory path of the program into a string. If you don't understand what I said, I recommend you stop begging for handouts and actually re-read what I said until you -do- understand it. If you still can't understand, I recommend going WAY back to really basic beginning programming. You're not going to acquire programming skills if you just get other people to do it for you.

Meanwhile, just to get you to ask a different question, here is a complete working program that does what you asked, and proves that it did it by printing it out.

#include <iostream>
#include <string>

int main (int argc, char *argv[])
{
    if (argc < 1) {
        std::cerr << "ERROR: program has zero arguments, "
                  << "cannot extract program-name" << std::endl;
        return 1;
    }

    std::string program_name (argv[0]);
    std::cout << "Program name is: " << program_name << std::endl;
    return 0;
}

Hi

I'm sorry for my previous reply. My deadline in closing in, so I thought it would be better if I got some spoon-feeding. :(

Here's my current main that I'm trying to use for copying the file path to a string path .

#include <iostream.h>
	 #include <string.h>
	 #include<conio.h>

	 int main (int argc, char *argv[])
	 {
	 clrscr();
	 char * path = strdup(argv[0]);
	 cout<<path;

	 for(int i=strlen(path);path[i]!="/";i--)
	 path[i]=" ";

	 getch();
	 return 0;
	 }

I'm trying to trim the current path C:\TC\BIN\PROG.EXE to C:\TC\BIN\ so I get the path to the current directory.

But again, since it's a char *, this won't work.

Any method to convert char * to char so I can work on the string normally?

One more thing, when I run this code in TC 4.5, I get the full path C:\TC\BIN\PROG.EXE but in TC 3, I get PROG.EXE .

I need to code the program in TC 3 only.

A couple of things.

If the desired version of TC doesn't provide the entire path to the executable in argv[0], you need to use one of the other methods suggested very early in this thread to get at it.

This won't help, since you only get the path in TC4.5, but just so you know:
+ in your for-loop at line 11, start with i=strlen(path)-1 (path[strlen(path)] is the terminating '\0' character, it's fine as-is, just something you typically don't want to look at)
+ also at line 11, check that i>=0, in case there's no slash mark in the string at all
+ elements of the string are chars, so compare chars (and assign them) to chars (use single-quotes instead of double)
+ both forward and backward slash characters are valid path separators in Windows, so check for both

I won't give you complete correct code for this at this point, since you need another approach to get the path anyway. Good luck.

A couple of things.

If the desired version of TC doesn't provide the entire path to the executable in argv[0], you need to use one of the other methods suggested very early in this thread to get at it.

This won't help, since you only get the path in TC4.5, but just so you know:
+ in your for-loop at line 11, start with i=strlen(path)-1 (path[strlen(path)] is the terminating '\0' character, it's fine as-is, just something you typically don't want to look at)
+ also at line 11, check that i>=0, in case there's no slash mark in the string at all
+ elements of the string are chars, so compare chars (and assign them) to chars (use single-quotes instead of double)
+ both forward and backward slash characters are valid path separators in Windows, so check for both

I won't give you complete correct code for this at this point, since you need another approach to get the path anyway. Good luck.

Okay. I'll try with something new and post my progress here.

And my main project is almost done.

Only the custom file paths are still hanging.

Okay. So I really can't come up with a way to get the path to work. Please someone help me. My whole project's foundation is the custom file path.

And I need to make the name of the file as "admission-number_name.txt". Now, admission-number is of type int, and name of char and I need to merge them into a new string.

I have tried to use std::stringstream , but TC doesn't support it.

My deadline is 18th Dec. :(

I've done some checking, and apparently Turbo C++ did have a version of the header <dir.h> , which may include a getcwd() which you can use. At least, I think that's what this thread implies (look down to the OP's reply to the first answer for the relevant comment).

EDIT: Further checking turns up a Google book copy of Programming in C++ by D. Ravichandran. According to this book, Turbo C++ 3.0 did have a getcwd() function, as well as another named getcurdir() . These should do what you need.

Thanks a lot man.

This is working just fine.

Now, I'll try to complete the project.

And I need to make the name of the file as "admission-number_name.txt". Now, admission-number is of type int, and name of char and I need to merge them into a new string.

I have tried to use std::stringstream , but TC doesn't support it.

Are you using C-strings or the string class? For the latter, you can just use string concatenation:

string filename = "admission-" + admitNumber + "_" + name + ".txt";

The string concatenation operator should automagically convert the integer values to a string, so long as there is a string value in the left-hand operand.

For C-strings, you can use sprintf() :

char filename[FILENAME_SIZE];

sprintf(filename, "admission-%d_%s.txt", admitNumber, name);

There's still one problem you may have to deal with: Turbo C++ is a DOS program, and MS-DOS only supported 8.3 filenames (that is, eight characters plus a three character extension). You may run into problems with the size of length of the filename you intend to use.

To overcome the 8.3 problem, I can merge 4 alphabets of the name, and 4 digits of the admission number (since admission number is 4 digits long).

As for the type of string, I'm simply using the char name[20];. I think this is C-style string.

So I tried this:

#include<iostream.h>
#include<string.h>
#include<conio.h>
#include<stdio.h>

using std::string;

void main()
{
clrscr();
char name[10], filename[20];
int admitNumber;
cout<<"Name: "; gets(name);
cout<<"No: "; cin>>admitNumber;
string filename = "admission-" + admitNumber + "_" + name + ".txt";
cout<<filename;
}

And got three error:

[IMG]http://i.imgur.com/S3abF.png[/IMG]

This was in bot TC 3, and TC 4.5.

But the below code

#include<iostream.h>
#include<string.h>
#include<conio.h>
#include<stdio.h>

void main()
{
clrscr();
char name[10];
int admitNumber;
cout<<"Name: "; gets(name);
cout<<"No: "; cin>>admitNumber;
	 char filename[20];
	 sprintf(filename, "admission-%d_%s.txt", admitNumber, name);
cout<<filename;
}

works in both. :)

Thanks a lot man.

Now, I think I'll be able to complete my program. :)

Okay so I'm using this function:

void report::generate()
{
cout<<endl;
ofstream mainlist;       //Object to change contents of mainlist.txt
	mainlist.open("mainlist.txt", ios::app);
ofstream report;
char fname[150], ch, directory[100];

getcwd(directory, sizeof(directory));
cout<<"Directory: "<<directory<<endl;

cout<<"Student's Name: "; gets(s.name);
cout<<"Admission Number: "; cin>>s.admno;
cout<<"Marks: "<<endl;
	for(int i=0;i<5;i++)
	{
		cout<<"\tSubject "<<i+1<<": "; cin>>s.marks[i];
	}
cin.get(ch);
s.perc=(s.marks[0]+s.marks[1]+s.marks[2]+s.marks[3]+s.marks[4])/5;
cout<<"Percentage is "<<s.perc<<endl;

sprintf(fname, "%d\Reports\%d.txt", directory, s.admno);
cout<<"File path: "<<fname;

report.open(fname, ios::out);

report.write((char *)&s, sizeof(s));

cout<<"Report card has been prepared";
report.close();

mainlist<<s.name<<"\n"<<s.admno<<"\n";
mainlist.close();
}

And this is the output:

[IMG]http://i.imgur.com/JHt5K.png[/IMG]

So the directory path is fine, but the file path that I'm creating using appending is not fine. Any ideas why?

Try changing the sprintf() like this:

sprintf(fname, "%s\\Reports\\%d.txt", directory, s.admno);

The '%s' is used to interpolate strings, while '%d' is used to interpolate decimal integers. When you use '%d' on a C-string - which is, after all, just a pointer - you get the address of the string in question.

You also need to use double backslashes ('\\') for the path, as single backslashes are treated as escape markers. To show the backslash itself, you need to escape the escape character, as it were.

commented: Thanks +1

Thanks a lot man.. It works awesomely now. :)

Will report back if I got any other hiccups.

A hiccup already.

The code was working in TC 4.5 and not in 3. I nee to make my project work in TC 3.

Any help? :(

What is the specific error that is occurring? Is it failing to compile, and if so, what does the error message say?

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.