PACS (Reading/Writing Files)

Hey Guys,
My name is Ian. I'm looking for some help on an assignment for my C++ class at a community college. We are asked to create a mock PACS interface. The program starts by presenting the user with a menu of 5 options. Each performs a different function and the program loops continuously until prompted to close (one of the menu options). One menu option writes user input to a text file, option two checks to see if a file exists, three displays the contents of a certain file, four just outputs "hello," and five exits the program. I'm sorry if that is a little vague.

Full Assignment Sheet on my Dropbox:
https://www.dropbox.com/s/9hj3zc6vmbw8xxt/Project%202%20-%20PACS.docx.pdf?dl=0

My two big issues right now are the looping and the reading and writing to file. Sorry if I'm being redundant (I have seen similar posts in this forum) and sorry that my code is super ugly. Anyway, here is my solution thus far...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int n = 0;
string filename;

int main()
{

    while (n == 0){
    /*Menu Contents*/
    cout << "***** Welcome to PACS! *****" << endl;
    cout << "Choose an option:" << endl;
    cout << "[1] C-STORE" << endl;
    cout << "[2] C-FIND" << endl;
    cout << "[3] C-GET" << endl;
    cout << "[4] C-ECHO" << endl;
    cout << "[5] Exit the program" << endl;
    cout << "Enter choice [1-5]: ";
    cin >> n;

    if (n == 1){
        cout << "Enter image filename: ";
        cin >> filename;
        ofstream myfile;
        myfile.open ("filename.txt");
        myfile << filename;
        myfile.close();
        cout << "Image successfully stored." << endl << endl;
        n = 0;
    }
    else
        if (n == 2){

        }
        else
            if (n == 3){

            }
            else
                if (n == 4)
                    cout << "Hello." << endl << endl;
                else
                    if (n == 5){

                    }
                    else
                        cout << "Please input an integer in the specified range [1-5]." << endl;
                        n = 0;
    }
    return 0;
}


Side note: The program does not handle user input of the wrong datatype. If input is of type double or a string for example the program will just loop endlessly without prompting for additional input.
Last edited on
You read from a file in a similar manner to writing to a file, but you use ifstream objects instead, and instead of the << operator, use the >> operator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <fstream>
#include <iostream>

int main()
{
    std::ifstream is("test.txt");
    if (!is)
    {
        std::cout << "Error, can't open test.txt" << std::endl;
    }

    // at this point, successfully opened the file for reading
    string item; // could be an int, or whatever you need it to specifically be
    while (is >> item) // store the data in item
    {
        std::cout << "item: " << item << std::endl;
    }
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
    else
        if (n == 2){

        }
        else
            if (n == 3){

            }
            else
                if (n == 4)
                    cout << "Hello." << endl << endl;
                else
                    if (n == 5){

                    }
                    else
                        cout << "Please input an integer in the specified range [1-5]." << endl;
                        n = 0;
    }
    return 0;

This indentation is misleading and unnecessary.
More appropriate would be:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
int main()
{
    while (true)
    {
        if (...) {
    
        }
        else if (n == 2) {
    
        }
        else if (n == 3) {
    
        }
        else if (n == 4) {
            cout << "Hello." << endl << endl;
        }
        else if (n == 5) {
    
        }
        else {
            cout << "Please input an integer in the specified range [1-5]." << endl;
            n = 0;
        }

    }

    return 0;
}


Instead of looping on while (n == 0), I would simplify it and just do

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
while (true)
{
    int n;
    cin >> n;
    if (n == 1)
    {
        // ...
    }
    // ...
    else if (n == 5)
    {
        break; // break out of the loop immediately
    }

}
return 0;


For option1, the server should prompt for an image filename (example kneexray.img)

do that like this, for example:
1
2
3
    std::string image_filename;
    cout << "Enter image filename: ";
    cin >> image_filename;


To display the contents of a file to the user, do something like this:
1
2
3
4
5
6
    std::ifstream f("file.txt");

    if (f.is_open())
        std::cout << f.rdbuf() << std::endl;
    else
        std::cout << "failed to open file" << std::endl;
Last edited on
Ganado,

Thanks for the help. So far I cleaned up my formatting and simplified the loop as you suggested which all seemed very intuitive for me, but when I went to work with reading/writing to/from the file I believe I made a mess again. In option one, any user input with a space breaks the program. Decimal input for select an option menu still breaks the program. I also think that I may be misunderstanding this concept fundamentally. Where is the file actually created (does it create a directory with the .cpp)?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    int n;

    while (true) {

        /*Menu Contents*/
        cout << "***** Welcome to PACS! *****" << endl;
        cout << "Choose an option:" << endl;
        cout << "[1] C-STORE" << endl;
        cout << "[2] C-FIND" << endl;
        cout << "[3] C-GET" << endl;
        cout << "[4] C-ECHO" << endl;
        cout << "[5] Exit the program" << endl;
        cout << "Enter choice [1-5]: ";
        cin >> n;    //program still does not handle floating-point input

    if (n == 1) {
        string image_filename;
        cout << "Enter image filename: ";
        cin >> image_filename;  //can't accept input with spaces
        ofstream myfile; 
        myfile.open ("file.txt");
        myfile << image_filename;
        myfile.close();
        cout << "Image successfully stored." << endl << endl;
        n = 0;
    }
    else if (n == 2) {
        string filename_query;
        cout << "Enter filename for verification: ";
        cin >> filename_query;
    }
    else if (n == 3) {
        
        string filename_query;
        cout << "Enter filename to view its contents: ";
        cin >> filename_query;
        ifstream myfile;
        myfile.open (filename_query);
        ifstream f("file.txt");

        if (myfile.is_open())
            cout << f.rdbuf() << endl;
        else
            cout << "failed to open file" << endl;
    }
    else if (n == 4) {
        cout << "Hello." << endl << endl;
    }
    else if (n == 5) {
        break;
    }
    else {
        cout << "Please input an integer in the specified range [1-5]." << endl;
        n = 0;
    }
}
    return 0;
}

In option one, any user input with a space breaks the program.
cin >> is space-delimited. In order to put in a name with spaces, you have to use getline.

1
2
3
4
5
6
7
8
        string image_filename;
        cout << "Enter image filename: ";
        getline(cin, image_filename);
        cin.ignore(); // ignore the remaining newline in the cin's buffer.

        ofstream myfile; 
        myfile.open ("file.txt");
        myfile << image_filename;


Decimal input for select an option menu still breaks the program

n is an int. This means integer, {..., -2, -1, 0, 1, 2, 3...}. You can't put a floating-point number in an int. Why do you want to do this? All of your options are ints {1, 2, 3, 4, 5}.

Where is the file actually created

If you only provide a name, the file is created in the same place that your program is being run from. On some IDEs, the "working directory" of execution is sometimes where your project file is, other times it might be in a bin/Debug or bin/Release folder.
Alternatively, you could choose to open absolute paths, str = "C:/foo/my_file.txt".

_________________________________

1
2
3
4
5
6
        ifstream myfile;
        myfile.open (filename_query);
        ifstream f("file.txt");

        if (myfile.is_open())
            cout << f.rdbuf() << endl;

You declared two file streams here, my_file and f. Get rid of f, and then change f.rdbuf() to myfile.rdbuf()
Topic archived. No new replies allowed.