Hello,
I have spent numerous hours re-working this code and I hope someone can clear up my confusion! This program asks the user to enter a file name which will then create and display that file with a poem in all caps.

The user is again prompted to enter another file name to hold a revised copy of the poem where the text is all lowercase and the first letter is capitalized.

I think my problem lies in the capital function(). Only the first line capitalizes. I have gotten it t work in using cout, but it doesn't update the saved file.

I am confused in using the ifstream & ofstream in the same file at the same time so maybe my logic in where I am placing the declarations is off. I just don't know! I just want it to work so that I can then add the error checking and format/tweak it.

Thank you for any help you can give,
Natalie

#include <iostream>
#include<fstream>
#include<cstring>
#include <string>
using namespace std;

void creatingInputFile(char[]);
void printPoem1(char[]);
void conversion(char[]);
void capital(char[]);

int main()
{
char inputName1[50];
char inputName2[50] = {'.', 't', 'x', 't'};
//ofstream outfile("con");

cout<<"Make up a file name to see a poem:"<<endl;
cin>>inputName1;
strcat(inputName1, inputName2);
cout<<"Thanks! The poem's file name is: " <<inputName1<<endl<<endl;
creatingInputFile(inputName1);
cout<< "The poem in "<<inputName1 << " is: "<<endl;
printPoem1(inputName1);
conversion(inputName1);

}//end of main()
void conversion(char poem1[])
{
    char file1[50];
    char file2[50] = {'.', 't', 'x', 't'};
     ofstream outfile;
    cout<<"Let's fix this poem up & give it a new name."<<endl;
    cout<<"Enter a new file name:"<<endl;
    cin>>file1;//file name of second poem
     strcat(file1, file2);//adding .txt file extension
    outfile.open(file1, ios::out);//creating second poem's name
    cout<<"Thanks! The second's poem's file name is: " <<file1<<endl<<endl;
    ifstream infile;
    infile.open(poem1, ios::in);
    char ch,ch2;
    while(infile.get(ch))
            {
                ch2=tolower(ch);
                outfile.put(ch2);
            }

        infile.close();
        outfile.close();
        capital(file1);
//printPoem1(file1);
}

void capital(char file1[])
{
    fstream infile;
    infile.open(file1, ios::in);    //open up lowercase input file
    cout<<"In capital()"<<endl;

    char line[200];
    ofstream outfile;
    while (!infile.eof())
    {
        infile.getline(line,200);
        int i=0;
        if(isalpha(line[i]))
            {
                 outfile.open(file1,ios::out);
                  line[i] = toupper(line[i]);
                  outfile<<line<<endl;
                       //outfile.put(line[0]);
                       //cout<<line<<endl;
             }

    }//end of while
    printPoem1(file1);
    infile.close();
    outfile.close();
    /*
    cout<<"There are "<<linecount<<" lines" <<endl;
    cout<<strlen(line)<<endl;
    int i=0;
    if(isalpha(line[i]))
       {
           line[i] = toupper(line[i]);
       }
*/

}

void creatingInputFile(char fileName[])
{
   ofstream inFile(fileName);
    inFile<<"ROSES ARE RED."<<endl;
    inFile<<"VIOLETS ARE BLUE."<<endl;
    inFile<<"SUGAR IS SWEET."<<endl;
    inFile<<"AND SO ARE YOU."<<endl;
    inFile.close();
}//end of creatingInputFile()

void printPoem1(char fileName[])
{
    ifstream infile(fileName);
    string dataLine;
    while(!infile.eof())
    {
        getline(infile, dataLine);
        cout<<dataLine<<endl;
    }
}//end of printPoem1

Recommended Answers

All 5 Replies

For each line you re-open the outfile in ios::out mode. This will always overwrite the file starting at position 0. Try opening outfile once before the loop:

ofstream outfile(file1);

while (infile.getline(line,200)) {
    line[0] = toupper(line[0]);
    outfile<< line <<'\n';
}

Note that using eof() as a loop condition is a bug, you'll end up processing the last line twice. And toupper does the right thing regardless of which character you give it, so there's no need to check if it's an alphabetical character first.

I think my problem lies in the capital function(). Only the first line capitalizes. I have gotten it t work in using cout, but it doesn't update the saved file.

I am confused in using the ifstream & ofstream in the same file at the same time so maybe my logic in where I am placing the declarations is off. I just don't know! I just want it to work so that I can then add the error checking and format/tweak it.

Your technique for learning to program needs work. Your technique is to write the entire program and try to fix everything at once. A better technique is to write 1 single necessary piece, get it working, then add the next piece.

So, if you are having trouble understanding I/O, write only that piece.
1a) Read the file
1b) Display what was read and make sure it's correct.
Now move on.

2a) Add write the file
2b) Check the file and make sure it's correct.
Now move on.

3a) Add capitalize the date
3b) Display the new data and make sure it's correct
...


So I'd start again and take it a step at a time. Use what you have as a template.

For each line you re-open the outfile in ios::out mode. This will always overwrite the file starting at position 0. Try opening outfile once before the loop:

ofstream outfile(file1);

while (infile.getline(line,200)) {
    line[0] = toupper(line[0]);
    outfile<< line <<'\n';
}

Note that using eof() as a loop condition is a bug, you'll end up processing the last line twice. And toupper does the right thing regardless of which character you give it, so there's no need to check if it's an alphabetical character first.

Thank you for your help,
opening the output file before the loop doesn't help at all:(
I did clear up the isapha, you were right!
I have been reworking it and going step by step but to no avail ....

opening the output file before the loop doesn't help at all

Ah, I see. You've got a booger of a problem in that both the streams are trying to access the same file. It's generally best not to introduce that kind of concurrency issue, or if you do, be very explicit about how you handle it:

void capital(char file1[])
{
    fstream file(file1, ios::in | ios::out);
    char line[200];

    while (true) {
        // Save the current write position
        fstream::pos_type set = file.tellp();

        if (!file.getline(line, sizeof line))
            break;

        line[0] = toupper(line[0]);

        // Overwrite the old string with the new one
        file.clear();
        file.seekp(set);

        // Be sure to flush so we can safely switch modes
        file<< line <<endl;
    }

    file.close();
    printPoem1(file1);
}

Ah, I see. You've got a booger of a problem in that both the streams are trying to access the same file. It's generally best not to introduce that kind of concurrency issue, or if you do, be very explicit about how you handle it:

void capital(char file1[])
{
    fstream file(file1, ios::in | ios::out);
    char line[200];

    while (true) {
        // Save the current write position
        fstream::pos_type set = file.tellp();

        if (!file.getline(line, sizeof line))
            break;

        line[0] = toupper(line[0]);

        // Overwrite the old string with the new one
        file.clear();
        file.seekp(set);

        // Be sure to flush so we can safely switch modes
        file<< line <<endl;
    }

    file.close();
    printPoem1(file1);
}

Thank you for shedding light on this for me, I didn't think to use those member functions seekp() or tellp(), I thought I would be able to do it without it. I started working on a for loop but that was not working either! I am gonna review those functions some more & a HUGE THANKS!!!!YOU ROCK!!!!

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.