1

This question sort of encompasses two problems (which may very well be inter-related) that I have been having in C#. I really hope this hasn't been clearly answered elsewhere, as I am unsure of what search terms to use and so far haven't come across anything that has satisfactorily explained it to me. I have a function called isHighScore() in my C# word game. Basically what's happening is that no matter the different ways I have tried formatting this, removing the usings, the try/catch's, I seem to be unable to write the variable to the file. I have edited the code down significantly for anyone reading this for the first time in order illustrate what appears to be (for me) more of an issue with scope.

private void isHighScore() //Having problems...
    {
        string strHighScore;

        try
        {
            StreamReader readHighScore = new StreamReader(strPath + "WAHS.txt")

            strHighScore = readHighScore.ReadLine(); 
        }
        catch (Exception e)
        {
                MessageBox.Show(Convert.ToString(e.Message));
        }
...

Next I would insert a similar block using StreamWriter and my comparison for userScore being greater than strHighScore doesn't seem to evaluate true. Is it because my variable goes out of scope? How can I read the changed value outside of the scope of that try-catch, or for that matter, a using statement with StreamReader (which I know is the preferred method).

armadadrive
  • 963
  • 2
  • 11
  • 42
  • 1
    Are you familiar with using blocks? You should have both the StreamReader and StreamWriter in one. Doing so makes the explict calls to Close unnessecary. [MSDN Page](http://msdn.microsoft.com/en-us/library/yh598w02(v=vs.110).aspx) – JG in SD Nov 16 '12 at 17:59
  • 3
    Side note: Try to only use comments where necessary. I know beginner programmers are taught to "always comment your code", but that's not productive if the comments are useless. `writeHighScore.Close(); //close streamwriter` is a useless comment - you know what `writeHighScore` is, and you know what the `Close()` method is doing. Why put a comment stating the obvious? – Dave Zych Nov 16 '12 at 18:01
  • Yes, in the beginning I had my streamreader and streamwriter in using blocks. You're seeing my "I'm pulling my hair out trying new things" function. And sorry for the over-commenting, I don't typically comment the hell out of my own code but for some reason I was worried I would be chastised here if I didn't. Go figure... ;) – armadadrive Nov 16 '12 at 18:13

2 Answers2

4

I'd strongly urge you to get rid of the manual calls to Close entirely. Use using statements instead. In fact, you don't need the StreamReader at all, if you use convenience methods provided by File:

string fileName = Path.Combine(path, "WAHS.txt");
string highScoreLine = File.ReadLines(fileName).First();

string beforeSpace = highScoreLine.Split(" ")[0];
int highScore = int.Parse(beforeSpace);

int userScore = int.Parse(txtScore.Text);
if (userScore > highScore)
{
    MessageBox.Show("Congratulations! You set a new high score!", "High Score");
    File.WriteAllText(fileName, userScore.ToString());
}

Any exceptions thrown by the above code should probably be caught and handled elsewhere, higher up the stack.

(Note that your current code would just write the existing high score back to the file, not the new one.)

If you're confident the file would only contain that line of text, you could just use File.ReadAllText instead.

Addressing the fundamental issue behind your confusion is possibly more important though. Do you understand why you can't access readHighScore in the place you're trying to close it?

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Hah. I hadn't even noticed that it was re-writing the high score, partly because it hasn't successfully written anything! Thanks for pointing that out. I will try your method, and yes, after I've posted this example I can see that readHighScore doesn't exist outside of the try-catch statement. I guess that's my fundamental problem - assuming I wanted to use StreamReader, how do I read in the existing high score to a variable that can be read outside of the try-catch? – armadadrive Nov 16 '12 at 18:16
  • @armadadrive: You'd need to declare the variable before the `try` block - and then you'd need to make sure it was definitely assigned, even if an exception is thrown and then caught. It would get ugly - that's part of the problem with trying to keep going even if something goes wrong. – Jon Skeet Nov 16 '12 at 18:18
  • Yeah, I seem to have identified that as the fundamental problem. When I first wrote the code with using statements and StreamReader/Writer, my conditional statement testing the value read from the file against the current score would never evaluate properly and I think it's because the variable read from the file was no longer in scope. – armadadrive Nov 16 '12 at 18:43
  • would having my streamreader and stream writer in the same using block fix the issue? Perhaps just use a temp file for the write and then perform an overwrite or append to the original once I had finished executing my statements? I feel like that would solve the scope issue. Your File method works fantastically but I want to understand the fundamental problem so I have the knowledge going forward. – armadadrive Nov 17 '12 at 19:09
  • 1
    @armadadrive: Yes, you could use the same block (or one block nested within another) but then you'd still have the file open for read when you tried to write. If you really want to use `StreamReader` and `StreamWriter` directly, you should declare the "high score read from file" variable *outside* the `using` statement, so it's still in scope later. – Jon Skeet Nov 17 '12 at 19:13
0

It is all about scope

Try-catch creates a new scope..

For example

try
{
int x=100;
}

catch
{
}
x=55;//you cant access x here

But,this would work

int x=0;
try
{
x=100;
}
catch
{
}
x=55;//valid..

So,Finally,Catch block cannot access variables that are declared within the Try block.

More info here

More general info here

Community
  • 1
  • 1
Anirudha
  • 32,393
  • 7
  • 68
  • 89
  • While the latter example you gave *is* valid, you couldn't *read* the variable, as it wouldn't be definitely assigned. – Jon Skeet Nov 16 '12 at 18:05
  • @JonSkeet thxx to point it out :)..i am currently into `c++` and far away from `c#`s strict checking! – Anirudha Nov 16 '12 at 18:08
  • What happens if you assign a value you to it inside and try to read it outside? In your second example if you just output x _after_ the try/catch, wouldn't it be uninitialized? For example, if your try didn't work and an exception was thrown, x would never be given a value. – armadadrive Nov 16 '12 at 18:11