0

I have a text file which holds input data for a guest at a hotel (Name, Nights staying, Corporate guest?). In the text file it will be displayed as

Ron,5,0
David,2
Ben,4,0

The format is Name,Number of Nights, Corporate Guest. The 0 you can see in some lines indicates they are a corporate guest. If there's no 0 they are not a corporate guest.

This is the code I use to create the file and write to it:

// Creates file to open and to write to
StreamWriter X = new StreamWriter("Guests.txt");
// File will be written to : File Handling\bin\debug

for (int i = 0; i < 8; i++)
{
    WriteLine();
    Write("What is Guests name? : ");
    name = ReadLine();
    Write("How many nights are they staying? : ");
    NightsStaying = int.Parse(ReadLine());
    Write("Corporate Guest? (Y/N) : ");
    CorporateGuest = Convert.ToChar(ReadLine());

    if (CorporateGuest == 'Y')
    {
        X.WriteLine($"{name},{NightsStaying},{accBalance}");
    }
    else
    {
        X.WriteLine($"{name},{NightsStaying}");
    }
}
X.Close();

Next, I created an object array, like this:

object[] arr = new object[10];

My problem now is I need to read in all this data and store in the array, so it can later be displayed on console. I also need to be able to know which records are regular Guests, and which are Corporate Guests.

Any help would be appreciated

7
  • 4
    Beginners have a strange reluctance to create classes. Don't be like that. Commented Jul 25, 2019 at 17:31
  • @DourHighArch This has all been done in the same class though? Commented Jul 25, 2019 at 17:35
  • @RhysHudson You can have more than one class. Write a class to represent a guest. Give it properties to match the columns in the text file. Call that class Guest. Write a method that takes one line of text from the file, parses it, and returns a new Guest instance with those values. Store your guests in a List<Guest>, not in an array. It's not common to actually use an array in C#. Commented Jul 25, 2019 at 17:35
  • @EdPlunkett This where my problem arises i don't quite understand how to read in the file and then make it decide whether its a corporate guest or not to store it in the list Commented Jul 25, 2019 at 17:42
  • 1
    Break your task down into small problems. Need to read text from a File? Then the File class should be useful. Particularly ReadLines. Then figure out how to convert a line to an object. Then figure out how to store a collection of those objects. Then figure out how to loop over that collection and write the output to the console. Break it down into small tasks, research each task. Commented Jul 25, 2019 at 17:45

2 Answers 2

2

You're looking for something like this.

As they said in the comments, split the task into smaller tasks, research a lot and go start filling the blanks.

Please mark as answer if it helps.

public class Program
{
    public static void Main(string[] args)
    {
        var guests = new List<Guest>();
        var lines = File.ReadLines("path/to/your/file.txt");

        foreach (var line in lines)
        {
            // TODO: parse line and extract data into variable.
            // You're doing it already...
            var name = "";
            var nightsStaying = 0;
            var isCorporate = false; 

            guests.Add(new Guest(name, nightsStaying, isCorporate));
        }

        var outputLines = guests.Select(guest => GuestFormatter.Format(guest));
        File.WriteAllLines("path/to/your/output-file.txt", outputLines);
    }
}

public class Guest
{
    public Guest(string name, int nightsStaying, bool isCorporate)
    {
        Name = name;
        NightsStaying = nightsStaying;
        IsCorporate = isCorporate;
    }   

    public string Name { get; } 
    public int NightsStaying { get; }
    public bool IsCorporate { get; }
}

public static class GuestFormatter
{
    public static string Format(Guest guest)
    {
        return $"{guest.Name},{guest.NightsStaying},{guest.IsCorporate}";
    }
}
Sign up to request clarification or add additional context in comments.

1 Comment

You could have a GuestParser class, that would accept a CSV string and return a Guest instance. The point in not having it all under a single method is that you have to split responsibilities in your code. Each module you create should be responsible for a single piece of funcionality of your software (search for SRP - Single Responsibility Principle).
0

Like others have suggested, you should definitely use a class to store guest data. Let's name it Guest. The class would look something like this:

public class Guest
{
    public string Name { get; set; }
    public int Nights { get; set; }
    public bool CorporateGuest { get; set; }
}

Note:

I'm not quite clear about your logic with Corporate Guest, and it doesn't look a very sound way of doing things. In your explanation you say that you store a 0 if it's a Corporate Guest, and nothing for a regular guest. In your code, you seem to write the value of accBalance, but if we go by your explanation it must always be a 0. I suggest, as I've done in my Guest class, to declare a bool member variable to represent whether a given guest is corporate or not. This will give you the added advantage of each line in the file having same number of columns.

Next, break down your problem. Use different functions to do different tasks, and have one function do only one thing. Since you need to get the same set of inputs, you should write a method that will take in guest information, and give it to you as a Guest object. Something like the following. Do note that I haven't done much error handling.

private static Guest GetGuestInfo()
{
    Console.Write("Guest Name: ");
    var name = Console.ReadLine();
    Console.Write("Nights Staying: ");
    int.TryParse(Console.ReadLine(), out int nights);
    Console.Write("Corporate Guest? (Y/N): ");
    var corporate = Console.ReadLine();

    var guest = new Guest
    {
        Name = name,
        Nights = nights
    };
    if (corporate == "Y")
        guest.CorporateGuest = true;
    else
        guest.CorporateGuest = false;

    return guest;
}

Then, for writing, use another function. I've changed writing to suit my suggestion, that you'd write the true/false boolean value to the file.

private static void WriteGuestToFile(StreamWriter sw, Guest guest)
{
    if (guest != null)
    {
        sw.WriteLine($"{guest.Name},{guest.Nights},{guest.CorporateGuest}");
    }
}

Now in your main program you can simply call these methods:

static void Main()
{
    var guests = new List<Guest>();
    for (int i = 0; i < 2; i++)
    {
        guests.Add(GetGuestInfo());
    }

    using (StreamWriter sw = new StreamWriter("Guests.txt"))
    {
        foreach (var guest in guests)
        {
            WriteGuestToFile(sw, guest);
        }
    }

    Console.ReadLine();
}

Note that StreamWriter is used with a using, which takes care of closing it and releasing memory for you, which is a recommended way of using any stream objects.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.