简体   繁体   中英

C# - Filling an array using a Strings chars doesn't work properly

I've got an

int[,] map = int[100, 100];

and a

String mapString;

mapString simply contains a large amount of numbers (there are no other chars than numbers).

I now want to assign the first value in the array( map[0,0] ) with the first char of mapString , the second value( map[0,1] ) with the second char of mapString and so on. I use the following code:

int currentposition = 0;
for (int x = 0; x < 100; x++)
{
    for (int y = 0; y < 100; y++)
    {
        map[x, y] = ArrayTest.Properties
                             .Settings
                             .Default
                             .mapSaveSetting
                             .ElementAt(currentposition);
        currentposition++;
    }
}

Now what happens is almost what I wished for. The problem is that it assigns two numbers to each value instead of one. Also i can't figure out what numbers he's using as they're not the ones in my mapSaveSetting , but I can deal with that for myself.

The only problem I really don't get is that each value contains two numbers after executing this for-loop. Why does it happen? ElementAt(int) only returns one char, right?

It really looks like a logical mistake to me but I can't find it. Please don't be offensive if I just made a dumb mistake in my way of thinking.

EDIT As it seems to be unclear what is the problem now, I'll add an example.

map[0, 0] == 42

...could be an output. Even if the String would start with eg 4245634 it would not make sense, as ElementAt(int) should only return the 4, not 42, right?

You are assigning char to int .Since there is implicit conversation from char to int you are getting the Unicode code of the character (in your case characters representing numbers).To fix you issue you should convert character to int. In your case as the all characters are numeric you can do as trick like this:

map[x, y] = 
   ArrayTest.Properties.Settings.Default.mapSaveSetting.ElementAt(currentposition) - 48;

This work because Unicode codes of symbols [0..9] sequential and equals to [48..57].

I think that your mistake is related to the ASCII value of the characters. You should know that each character has a related ASCII value, in particular 0 has an ASCII value of 48 , 1 of 49 and so on (you could check an ASCII table to check this out).

So, to get the right value of the character, you should subtract the value of the char 0 from the one in the string, like in the following piece of code.

map[x, y] = ArrayTest.Properties.Settings.Default.mapSaveSetting.ElementAt(currentposition) - '0';

You are assigning a char value to an int . A char designs a Unicode code point, and it converts implicitly to int but not in the way you expect: it gives you the code point.

Example:

Console.WriteLine((int)'A'); // Will print 65

You're actually trying to convert a single digit represented as a string to an int . Use int.Parse for this.

Console.WriteLine(int.Parse("5")); // Will print 5

Another issue: you shouldn't use ElementAt on a string , since it will needlessly iterate over the whole string until the specified index, as string doesn't implement IList<char> .

You could use the indexer like that:

int currentposition = 0;
var setting = ArrayTest.Properties.Settings.Default.mapSaveSetting;

for (int x = 0; x < 100; x++)
{
    for (int y = 0; y < 100; y++)
    {
        map[x, y] = int.Parse(setting[currentposition].ToString());
        currentposition++;
    }
}

But it's actually a waste to convert each char in there to a new string , so just use some basic math instead:

int currentposition = 0;
var setting = ArrayTest.Properties.Settings.Default.mapSaveSetting;

for (int x = 0; x < 100; x++)
{
    for (int y = 0; y < 100; y++)
    {
        map[x, y] = setting[currentposition++] - '0';
    }
}

This works as the code points for the digits are consecutive.

To elaborate just a little on previous answers: In C and C++, a char is a byte (for all intents and purposes), while in C# it's a "Unicode" character. C# however has the 'byte' type matching pretty much 1:1 to the lower-level languages 'char' type.

The question suggests this could be a part of the issue.

Additionally (performance consideration): It should be noted that in C#, an array is a "heavy" type, and a multi-dimensional array is really an array-of-arrays. Depending on usage patterns, it could be more efficient to use a single-dimension array and scale one of the indices by row/col-size manually. Something like: type this[int x, int y] { get { /* scale one of x/y and read from 1-dimensional array */ } }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM