-1

Apart from the fact that I'm still a beginner in this language, I don't understand foreach very well.

public static void test ()
{
    string str = "";

    foreach (string line in str)
    {
        Console.WriteLine(line);
    }
}

using the var keyword, that's not what I want
I need to check string, and this is for file

CS0030: Cannot convert type 'char' to 'string'

I ask myself: why char??
btw, this is my code.
I'm doing this to try to detect lines in a .txt file

public static readonly string file_name = "medallion.txt"; 
public static void file ()
{
    var file = File.OpenWrite(file_name);  // open the txt file

    foreach (string line in File.ReadAllText(file_name))
    {
        if (line == string.Empty || line.StartsWith("//")) continue;  // trrying to do comments
    }
}
CS0030: Cannot convert type 'char' to 'string'
3
  • 11
    "I ask myself: why char" - because a string is a collection of characters, not a collection of strings. Commented Jun 26, 2024 at 13:36
  • 4
    foreach (string line in File.ReadAllText(file_name)) - A typo? Did you mean to use ReadAllLines instead? Commented Jun 26, 2024 at 13:37
  • 2
    foreach works with IEnumerable<T>, and string implements IEnumerable<char>, therefore you get a char. Commented Jun 26, 2024 at 13:51

2 Answers 2

4

When you use foreach with a string, you do NOT get lines! Nor should you. After all, a string is a sequence of characters.

Specifically, foreach works by calling GetEnumerator() and when you call string.GetEnumerator() you get a CharEnumerator (ie a sequence of characters).

When you need to loop through lines (instead of characters) of a string, you can use a StringReader (not StreamReader).

But in this case you have a file. To loop through the lines of a file, do NOT use File.ReadAllText(), and do NOT use File.ReadAllLines(), as suggested elsewhere, at least as your first choice.

Instead, look at File.ReadLines() (no All), again — at least as your first choice. This saves you from needing to load the entire file into memory all at the same time.

Additionally, looking at the final sample, as a matter of style it's much better if the method accepts the file_name as an argument and returns the data as a result.

Put it all together and we end up with this:

public static IEnumerable<string> LoadFile(string file_Name)
{
    return File.ReadLines(file_Name).
         Where(line => line != string.Empty && !line.StartsWith("//") );   
}

var file = LoadFile("medallion.txt");

Even better, we probably don't want to accept lines that are only white space or only have whitespace before the comment marker (while still preserving indentation that may be significant):

public static IEnumerable<string> LoadFile(string file_Name)
{
    return File.ReadLines(file_Name).
         Where(line => {
             var trimmed = line.Trim();
             return trimmed != string.Empty && !trimmed.StartsWith("//"); 
         });  
}

var file = LoadFile("medallion.txt");

But since you say you're a beginner, you may need it to look more like this:

public static List<string> LoadFile(string file_Name)
{
    var result = new List<string>();
    var lines = File.ReadLines(file_Name);
    foreach(string line in lines)
    {
        if (line != string.Empty && !line.StartsWith("//") )
        { 
            result.Add(line);
        }
    }
    return result;  
}

var file = LoadFile("medallion.txt");

Which is more code to be less efficient, but now the only advanced feature you need to know about is generic collections, which is still a concept typcially introduced to college CS students in the first or second year.

Sign up to request clarification or add additional context in comments.

Comments

3

When you iterate over a string, you iterate over each character in the string. So, if you were to iterate a string hello!, you would get the following chars: h e l l o !

File.ReadAllText reads the raw file content as a single string, which is also iterated by a char.

Use File.ReadAllLines instead, which returns a string array representing each line of a file:

string[] fileContent = File.ReadAllLines(file_name);
foreach (string line in fileContent)
{
    // do something with line
}

If you have the following contents in a file:

hello
world
!

then File.ReadAllLines would return a string array, consisting of these strings: hello world !

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.