Ok, I was trying to write a program that formats a plain text file to the formatting standards of gamefaqs.com (no trailing spaces and no more than 79 characters per line). To my eyes, my code looks perfectly fine and effective. If I run it with anything but a file that can be formatted, it runs as expected. That would lead me to believe the problem is in the format_file function, but I don't know where it is. When I run it with a file that actually contains formattable text, it terminates and gives me this message

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

And ends with status 3 (0x3). Here is the code

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

int format_file(string filename);

int main(int argc, char** argv)
{
    //next 5 lines only for diagnostic purposes
    printf("%d argument%s offered\n",argc-1,argc==2?" was":"s were");
    for (int a = 1; a < argc; a++)
    {
        printf("argv[%d] = %s\n",a,argv[a]);
    }

    string file;
    fstream checkfile;
    if (! argc > 1)
    {
        printf("No file argument was offered\nPlease offer a file to format");
        return 50;
    }
    else
        //check arguments 1 after another to see which can be formatted
        for (int a = 1; a < argc; a++)
        {
            checkfile.open(const_cast<char*> (argv[a]), ios::in | ios::ate);

            //check if file exists
            if (checkfile.fail())
            {
                printf("%s does not exist\nOperation aborted", argv[a]);
                return 40;
            }

            //check if file is empty
            else if (! checkfile.tellg() > 0)
            {
                printf("%s is empty\nNothing to be formatted", argv[a]);
                return 30;
            }

            //if file exists and contains content, format the file
            else
            {
                format_file(file);
                printf("%s formatted successfully", argv[a]);
            }
            if (checkfile.is_open())
                checkfile.close();
        }
        return 0;
}

int format_file(string filename)
{
    ifstream readfile;
    ofstream writefile;
    string file, line;
    unsigned int num = string::npos;

    //open readfile for reading and formatting
    readfile.open(filename.c_str(), ios::in);
    while (! readfile.eof())
    {
        getline(readfile, line);

        //check for words from previous line to add
        if (file.substr(file.length()-1) != "\n" && num != string::npos)
            line = file.substr(num+1) + line;

        //check for trailing spaces
        while (line.substr(line.length()-1) == " ")
            line.erase(line.length()-1);

        //check for lines too long
        if (line.length() > 79)
        {
            num = line.length();
            while (line[num] != ' ')
                num--;
            line[num]='\n';
            line += " ";
        }

        //concatenate line onto file
        file+=line;
    }
    //close readfile
    if (readfile.is_open())
        readfile.close();

    //write the resulting file into the filename
    writefile.open(filename.c_str(), ios::out | ios::trunc);
    writefile << file.c_str();
    //close writefile
    if (writefile.is_open())
        writefile.close();

    return 0;
}

I appreciate any help you may offer.

Recommended Answers

All 6 Replies

I read few lines of code. And so far I have found some silly mistakes

1) if (! argc > 1) will always fail because ! has higher priority than >

this priority stuff confuses me a lot so I always use () to aviod the confusion

2) the string file was never assigned a value.

Besides this need you open the same file twice ( once in main & once in sub_fn )

A couple of things, get rid of the eof() in the while() loop, instead use

int format_file(string filename)
{
    ...
    while (getline(readfile, line))
    {
    ...
    }
}

If 'line' contains only whitespace, then the following will crash because line.length()-1 will be negative

//check for trailing spaces
 while (line.substr(line.length()-1) == " ")
       line.erase(line.length()-1);

You don't have to use substr() to check for individual characters, better way is

if(line[ valid_index_here ] == ' ')
...

Thank you both for your help. I followed your advice and did a few extra tweaks, and now my program works to perfection. Thanks again.

Ok, one more question if you don't mind helping me out. I would like to make it so that if the line is less than 79 characters long, it will check the next line to see if the first word will fit on the current line without passing the 79 character limit. Problem is, I have no idea where to start. Here is the updated code

#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
#include <sstream>

using namespace std;

int format_file(string filename);

int main(int argc, char** argv)
{
    /*//next 5 lines only for diagnostic purposes
    printf("%d argument%s offered\n",argc-1,argc==2?" was":"s were");
    for (int a = 1; a < argc; a++)
    {
        printf("argv[%d] = %s\n",a,argv[a]);
    }*/

    string file;
    int check;
    if (! (argc > 1))
    {
        cout << "Please offer a file to format\n->";
        getline(cin, file);
        if (file == "")
            file = "IceClimbersFAQ.txt";
    }
    //format files and output the results
    int a = 1;
    do
    {
        if (argc >= 2)
            file = argv[a];
        check = format_file(file);
        if (check == 40)
            printf("%s does not exist\nOperation aborted", file.c_str());
        else if (check == 20)
            printf("%s is empty\nNothing to be formatted", file.c_str());
        else if (check == 0)
            printf("%s formatted successfully", file.c_str());
        a++;
    } while (a < argc);
    return 0;
}

int format_file(string filename)
{
    ifstream readfile;
    ofstream writefile;
    string file = "", line;
    unsigned int num = string::npos;

    //open readfile for reading and formatting
    readfile.open(filename.c_str(), ios::in | ios::ate);

    //check if file does not exist
    if (readfile.fail())
        return 40;

    //check if file is empty
    else if (! (readfile.tellg() > 0))
        return 20;

    //if file exists and contains content, go to the beginning to start formatting
    else
        readfile.seekg(0, ios::beg);

    //format one line at a time
    while (getline(readfile, line))
    {
        //check for trailing spaces
        while (line[line.size()-1] == ' ')
            line.erase(line.size()-1);

        //reformat the line while line is too long
        while (line.size() > 79)
        {
            //replace last space before 79th character with a newline
            num = line.size();
            while (line[num] != ' ' || num > 79)
                num--;
            line.replace(num,1,"\n");
            line += " ";

            //add line up to newline character to file and send remainder to check for reformatting
            file+=line.substr(0,line.find("\n")+1);
            line=line.substr(line.find("\n")+1);
        }

        //if line is not too long, concatenate line onto file and add new line
        if (line.size() <= 79)
            file+=line+"\n";
    }
    //close readfile
    if (readfile.is_open())
        readfile.close();

    //write the resulting file into the filename
    writefile.open(filename.c_str(), ios::out | ios::trunc);
    writefile << file.c_str();
    //close writefile
    if (writefile.is_open())
        writefile.close();

    return 0;
}

Thank you for any further help.

Ok, one more question if you don't mind helping me out. I would like to make it so that if the line is less than 79 characters long, it will check the next line to see if the first word will fit on the current line without passing the 79 character limit.

Remember the length of the line stored in 'file'. Then, when you read in a line, lookup the first space in the input, so you get the length of the first word and if the length is small enough, replace the last newline with a space and append the word + newline to 'file'. Of course, you could make it work so that multiple words will be appended to the last line.

Thank you all for your help. I found a few further problems that were just slight kinks so I scratched the whole thing and started over but used the same principle. Anyway, I have it all worked out and decided not to use the word check from the next line because that would screw up any ASCII art that might be in it. Anyway, thank you all for your help.

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.