Home > front end >  arrange line in txt file in ASCII order using array and display them
arrange line in txt file in ASCII order using array and display them

Time:04-23

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

using namespace std;

int main() {
    ifstream infile;          // ifstream is reading file
    infile.open("read.txt");  // read.txt is the file we need to read
    std::cout << infile;
    string str;
    if (infile.is_open()) {
        while (getline(infile, str)) {
            char str[2000], ch;
            int i, j, len;
            len = strlen(str);
            for (i = 0; i < len; i  ) {
                for (j = 0; j < (len - 1); j  ) {
                    if (str[j] > str[j   1]) {
                        ch = str[j];
                        str[j] = str[j   1];
                        str[j   1] = ch;
                    }
                }
            }
        }
        cout << "\nProcessed data:" << str;
    }

    return 0;
}

My txt file:

Today is a fine day.
It’s sunny.
Let us go out now!

My result should be:

    .Taaaddefiinosyy
 ’.Innsstuy
    !Legnooosttuuw

Spaces is consider here as well. I'm new to C . I need some pros help. Thank you very much!

CodePudding user response:

Making use of the STL:

  • Read your file into a std::vector<std::string>.
  • Use std::ranges::sort to sort every line before adding it to the vector of lines.

The example below:

  • also uses the fmt library instead of std::cout, and
  • reads from a std::istringstream instead of a std::ifstream.

[Demo]

#include <algorithm>  // sort
#include <fmt/ranges.h>
#include <sstream>  // istringstream
#include <string>  // getline
#include <vector>

int main() {
    std::istringstream iss{
        "Today is a fine day.\n"
        "It's sunny.\n"
        "Let us go out now!\n"
    };

    fmt::print("Original file:\n{}\n", iss.str());

    std::vector<std::string> lines{};
    std::string line{};
    while (std::getline(iss, line)) {
        std::ranges::sort(line);
        lines.push_back(line);
    }

    fmt::print("Processed file:\n{}", fmt::join(lines, "\n"));
}

// Outputs:
//
//   Original file:
//   Today is a fine day.
//   It's sunny.
//   Let us go out now!
//   
//   Processed file:
//       .Taaaddefiinosyy
//    '.Innsstuy
//       !Legnooosttuuw

CodePudding user response:

Your code will not work, because:

  1. The function std::strlen requires as a parameter a pointer to a valid string. Maybe you intended to write str.length()? In that case, you should delete the declaration char str[2000], because it shadows the declaration string str;.
  2. If you want to sort several strings, then you must remember all strings that you read in, by allocating space for these strings in memory. Although it would be possible to store multiple strings in a single array like char str[2000], this is probably not the ideal solution.

As already pointed in the comments section, this problem is a lot easier to solve in C using std::string instead of C-style strings, and using std::vector and std::sort:

#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cstdlib>

int main()
{
    std::ifstream infile( "read.txt" );
    std::string line;
    std::vector<std::string> lines;

    //verify that file was successfully opened
    if ( !infile )
    {
        std::cerr << "Error opening file!\n";
        std::exit( EXIT_FAILURE );
    }

    //read in all lines
    while ( std::getline( infile, line ) )
    {
        lines.push_back( line );
    }

    //sort the lines
    std::sort( lines.begin(), lines.end() );

    //output the sorted lines
    for ( auto &line : lines )
    {
        std::cout << line << '\n';
    }

    return 0;
}

For the input posted in the question

Today is a fine day.
It’s sunny.
Let us go out now!

this program has the following output:

It’s sunny.
Let us go out now!
Today is a fine day.

In the comments section of this answer, you stated that you are allowed to use std::string, but that you are not allowed to use std::vector or std::sort. Also, you seem also not allowed and/or able to use range-based for loops, as your compiler configuration does not seem to support ISO C 11. Therefore, I have also provided a (less-efficient) solution which uses a fixed-length array of std::string:

#include <iostream>
#include <fstream>
#include <cstdlib>

const int MAX_LINES = 100;

int main()
{
    std::ifstream infile( "read.txt" );
    std::string line;
    std::string lines[MAX_LINES];
    int num_lines = 0;

    //verify that file was successfully opened
    if ( !infile )
    {
        std::cerr << "Error opening file!\n";
        std::exit( EXIT_FAILURE );
    }

    //read in all lines
    while ( std::getline( infile, line ) )
    {
        //break out of loop if maximum number of lines
        //has been reached
        if ( num_lines == MAX_LINES )
        {
            std::cerr <<
                "Warning: Limit on the maximum number of lines "
                "has been reached.\n";
            break;
        }

        //copy line to array
        lines[num_lines  ] = line;
    }

    //sort the lines
    for ( int i = 0; i < num_lines - 1; i   )
    {
        for ( int j = i   1; j < num_lines; j   )
        {
            if ( lines[i] > lines[j] )
            {
                //NOTE: Using std::move or std::swap would
                //probably be more efficient, but I am not 
                //sure if you are allowed to use it.

                //swap the strings
                std::string temp = lines[i];
                lines[i] = lines[j];
                lines[j] = temp;
            }
        }
    }

    //output the sorted lines
    for ( int i = 0; i < num_lines; i   )
    {
        std::cout << lines[i] << '\n';
    }

    return 0;
}
  • Related