What is the meaning of UserName = String(33, 0) in VB 6.0 and what will be the equivalent in C#.
Please help I'm getting error while converting VB 6.0 code into C#.
Thanks in advance.
String in VB6 is a function that returns a string containing a repeating character string of the length specified.
String(number,character)
example:
strTest = String(5, "a")
' strTest = "aaaaa"
strTest = String(5, 97)
' strTest = "aaaaa" (97 is the ASCII code for "a")
In this case, String(33,0) will return a string containing 33 null characters.
The equivalent in C# would be
UserName = new String('\0', 33);
In VB6, that function creates a string that contains 33 characters, all of whom have zero ordinal value.
Typically you do that because you are about to pass the string to some native function which fills out the buffer. In C# the closest equivalent to that would be to create a StringBuilder instance which you would then pass to the native code in a p/invoke function call.
I think that a direct translation of that single line of code is not particularly useful. That code exists in context and I strongly suspect that the context is important.
So, whilst you could create a new C# string with 33 null characters, what would be the point of that? Since the .net string is immutable, you cannot do very much of interest with it. In your VB6 code you will surely be mutating that object, and so StringBuilder is, in my view, the most likely tool for the job.
I believe you are looking for:
UserName = new String((Char)0, 33);
Reference this for what the VB6 method did.
You can create an function that perform this action, or o can do a extenssion of the class String.
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(strGen("01",3));
}
//param s is the string that you can generete and the n param is the how many times.
private static string strGen(String s, int n){
string r = string.Empty;
for (int x = 1; x <= n; x++)
r += string.Copy(s);
return r;
}
}
Related
I didn't get the problem - I was trying to do a simple action:
for(i = x.Length-1, j = 0 ; i >= 0 ; i--, j++)
{
backx[j] = x[i];
}
Both are declared:
String x;
String backx;
What is the problem ? It says the error in the title...
If there is a problem - is there another way to do that?
The result (As the name 'backx' hints) is that backx will contain the string X backwards.
P.S. x is not empty - it contains a substring from another string.
Strings are immutable: you can retrieve the character at a certain position, but you cannot change the character to a new one directly.
Instead you'll have to build a new string with the change. There are several ways to do this, but StringBuilder does the job in a similar fashion to what you already have:
StringBuilder sb = new StringBuilder(backx);
sb[j] = x[i];
backx = sb.ToString();
EDIT: If you take a look at the string public facing API, you'll see this indexer:
public char this[int index] { get; }
This shows that you can "get" a value, but because no "set" is available, you cannot assign values to that indexer.
EDITx2: If you're looking for a way to reverse a string, there are a few different ways, but here's one example with an explanation as to how it works: http://www.dotnetperls.com/reverse-string
String is immutable in .NET - this is why you get the error.
You can get a reverse string with LINQ:
string x = "abcd";
string backx = new string(x.Reverse().ToArray());
Console.WriteLine(backx); // output: "dcba"
String are immuatable. You have convert to Char Array and then you would be able to modify.
Or you can use StringBuilder.
for example
char[] wordArray = word.ToCharArray();
In C# strings are immutable. You cannot "set" Xth character to whatever you want. If yo uwant to construct a new string, or be able to "edit" a string, use i.e. StringBuilder class.
Strings are immutable in C#. You can read more about it here: http://msdn.microsoft.com/en-us/library/362314fe.aspx
Both the variables you have are string while you are treating them as if they were arrays (well, they are). Of course it is a valid statement to access characters from a string through this mechanism, you cannot really assign it that way.
Since you are trying to reverse a string, do take a look at this post. It has lot of information.
public static string ReverseName( string theName)
{
string revName = string.Empty;
foreach (char a in theName)
{
revName = a + revName;
}
return revName;
}
This is simple and does not involve arrays directly.
The code below simply swaps the index of each char in the string which enables you to only have to iterate half way through the original string which is pretty efficient if you're dealing with a lot of characters. The result is the original string reversed. I tested this with a string consisting of 100 characters and it executed in 0.0000021 seconds.
private string ReverseString(string testString)
{
int j = testString.Length - 1;
char[] charArray = new char[testString.Length];
for (int i = 0; i <= j; i++)
{
if (i != j)
{
charArray[i] = testString[j];
charArray[j] = testString[i];
}
j--;
}
return new string(charArray);
}
In case you need to replace e.g. index 2 in string use this (it is ugly, but working and is easily maintainbable)
V1 - you know what you want to put their. Here you saying in pseudocode string[2] = 'R';
row3String.Replace(row3String[2], 'R');
V2 - you need to put their char R or char Y. Here string[2] = 'R' if was 'Y' or if was not stay 'Y' (this one line if needs some form of else)
row3String.Replace(row3String[2], row3String[2].Equals('Y') ? 'R' : 'Y');
I have been given some C# code which defined some Private String but I am not sure what it is doing honestly and need to convert into VB for my Project but wandered if someone might take a moment to explain and possible provide a conversion?
private string GetChecksum(StringBuilder buf)
{
// calculate checksum of message
uint sum = 0;
for (int i = 0; i < buf.Length; i++)
{
sum += (char)buf[i];
}
return string.Format("{0:X04}", sum);
}
The part with private string ... is the method declaration. C#'s
Accessibility ReturnType MethodName(Type paramName)
translates to
Accessibility Function MethodName(paramName As Type) As ReturnType
Private Function GetChecksum(buf As StringBuilder) As String
'calculate checksum of message
Dim sum As UInteger = 0
For i As Integer = 0 To buf.Length - 1
sum += CChar(buf(i))
Next
Return String.Format("{0:X04}", sum)
End Function
What the function does is adds up the ASCII values of each character in the string (stored in a 2-byte char without overflow checking) and return the result as a string - the 4-character hexadecimal representation of the 2-byte result.
A checksum is used to detect data errors; if two strings yield different checksums then they cannot be equal. Two strings that give the same checksum, however, are non necessarily equal, so it cannot be used to verify equality.
I'm coming from a C++ background. This question has been asked before, but try as I might I cannot find the answer. Let's say I have:
string[] ArrayOfReallyVeryLongStringNames = new string[500];
ArrayOfReallyVeryLongStringNames[439] = "Hello world!";
Can I create a string that references the above (neither of these will compile):
string a = ref ArrayOfReallyVeryLongStringNames[439]; // no compile
string a = &ArrayOfReallyVeryLongStringNames[439]; // no compile
I do understand that strings are immutable in C#. I also understand that you cannot get the address of a managed object.
I'd like to do this:
a = "Donkey Kong"; // Now ArrayOfReallyVeryLongStringNames[439] = "Donkey Kong";
I have read the Stack Overflow question Make a reference to another string in C#
which has an excellent answer, but to a slightly different question. I do NOT want to pass this parameter to a function by reference. I know how to use the "ref" keyword for passing a parameter by reference.
If the answer is "You cannot do this in C#", is there a convenient workaround?
EDIT:
Some of the answers indicate the question was unclear. Lets ask it in a different way. Say I needed to manipulate all items in the original long-named array that have prime indices. I'd like to add aliases to Array...[2], Array...[3], Array...[5], etc to a list. Then, modify the items in the list using a "for" loop (perhaps by passing the list just created to a function).
In C# the "using" keyword creates an alias to a class or namespace. It seems from the answers, that it is not possible to create an alias to a variable, however.
You could create a wrapper that keeps a reference to the underlying array AND the index of the string:
public sealed class ArrayStringReference
{
private readonly string[] _array;
private readonly int _index;
public ArrayStringReference(string[] array, int index)
{
_array = array;
_index = index;
}
public string Value
{
get
{
return _array[_index];
}
set
{
_array[_index] = value;
}
}
public override string ToString()
{
return Value;
}
}
Then this will work:
string[] ArrayOfReallyVeryLongStringNames = new string[500];
ArrayOfReallyVeryLongStringNames[439] = "Hello world!";
var strRef = new ArrayStringReference(ArrayOfReallyVeryLongStringNames, 439);
Console.WriteLine(ArrayOfReallyVeryLongStringNames[439]); // Outputs "Hello world!"
strRef.Value = "Donkey Kong";
Console.WriteLine(ArrayOfReallyVeryLongStringNames[439]); // Outputs "Donkey Kong"
You could make this more convenient to use by providing an implicit string operator so you don't have to use .Value to access the underlying string:
// Add this to class ArrayStringReference implementation
public static implicit operator string(ArrayStringReference strRef)
{
return strRef.Value;
}
Then instead of having to access the underlying string like this:
strRef.Value = "Donkey Kong";
...
string someString = strRef.Value;
You can do this:
strRef.Value = "Donkey Kong";
...
string someString = strRef; // Don't need .Value
This is just syntactic sugar, but it might make it easier to start using an ArrayStringReference in existing code. (Note that you will still need to use .Value to set the underlying string.)
The closest you can get is this:
unsafe
{
string* a = &ArrayOfReallyVeryLongStringNames[439]; // no compile
}
Which gives an exception:
Cannot take the address of, get the size of, or declare a pointer to a managed type ('string')
So no, not possible...
Also read this MSDN article which explains what types can be used (blittable types).
When I do something like this in C#:
string a = "String 1";
string b = a;
a = "String 2";
Console.WriteLine(a); // String 2
Console.WriteLine(b); // String 1
The thing is, both "String 1" and "String 2" literals are created at the start of the program, and strings are always pointers: at first a references "String 1" literal and afterwards it references "String 2". If you want them to always reference the same thing, in C# you just use the same variable.
The string objects themselves are immutable in C#:
Because a string "modification" is actually a new string creation, you must use caution when you create references to strings. If you create a reference to a string, and then "modify" the original string, the reference will continue to point to the original object instead of the new object that was created when the string was modified.
When the string mutability is needed, for example, to concatenate a lot of strings faster, other classes are used, like StringBuilder.
To sum it up, what you're trying to do is impossible.
In C#, a String is an Object. Therefore String a = "Donkey Kong" says that a now have a reference to this string that is being allocated over the memory. Then all you need to do is:
ArrayOfReallyVeryLongStringNames[439] = a;
And that will copy the refrence (which you should be thinking of in C#!!!) to the location in the string.
BUT!! When you do a="new string";, a will get a new reference. See the example I made:
http://prntscr.com/3kw18v
You can only do this with unsafe mode.
You could create a wrapper
public class StringWrapper
{
public string Value {get;set;}
}
StringWrapper[] arrayOfWrappers = new StringWrapper[500];
arrayOfWrappers[439] = new StringWrapper { Value = "Hello World" };
StringWrapper a = arrayOfWrappers[439];
a.Value = "New Value";
What you are trying to do is universally discouraged, and actively prevented, in C#, where the logic should be independent of the memory model, however, refer to related SO question C# memory address and variable for some info.
EDIT 1
A more canonical approach to your actual problem in C# would be:
// using System.Linq;
string[] raw = new string[] { "alpha", "beta", "gamma", "delta" };
List<int> evenIndices = Enumerable.Range(0, raw.Length)
.Where(x => x % 2 == 0)
.ToList();
foreach (int x in evenIndices)
raw[x] = raw[x] + " (even)";
foreach (string x in raw)
Console.WriteLine(x);
/*
OUTPUT:
alpha (even)
beta
gamma (even)
delta
*/
If you really want to modify the original memory structure itself, then perhaps C++ is a more appropriate language choice for the solution.
EDIT 2
Looking around on SO, you may want to look at this answer Hidden Features of C#? to an unrelated question.
[TestMethod]
public void TestMethod1()
{
string[] arrayOfString = new string[500];
arrayOfString[499] = "Four Ninty Nine";
Console.WriteLine("Before Modification : {0} " , arrayOfString[499]);
string a = arrayOfString[499];
ModifyString(out arrayOfString[499]);
Console.WriteLine("after a : {0}", a);
Console.WriteLine("after arrayOfString [499]: {0}", arrayOfString[499]);
}
private void ModifyString(out string arrayItem)
{
arrayItem = "Five Hundred less one";
}
Of course you can, hehe:
var a = __makeref(array[666]);
__refvalue(a, string) = "hello";
But you would have to have a very good reason to do it this way.
How can i make bitwise operations on strings at c#
example
string sr1="0101110";
string sr2="1101110";
sr1 & sr2="0101110";
or
sr1 | sr2="1101110";
How can i make such comparison ?
Notice string lengths are fixed 1440 characters
Here my dirty solution
private string compareBitWiseAnd(string sr1, string sr2)
{
char[] crArray1 = sr1.ToCharArray();
char[] crArray2 = sr2.ToCharArray();
StringBuilder srResult = new StringBuilder();
for (int i = 0; i < crArray1.Length; i++)
{
if (crArray1[i] == crArray2[i])
{
srResult.Append(crArray1[i]);
}
else
{
srResult.Append('0');
}
}
return srResult.ToString();
}
private string compareBitWiseOr(string sr1, string sr2)
{
char[] crArray1 = sr1.ToCharArray();
char[] crArray2 = sr2.ToCharArray();
StringBuilder srResult = new StringBuilder();
for (int i = 0; i < crArray1.Length; i++)
{
if (crArray1[i] == '1' || crArray2[i] == '1')
{
srResult.Append("1");
}
else
{
srResult.Append('0');
}
}
return srResult.ToString();
}
Convert to actual bits first, and then do the bitwise comparison.
int num1 = Convert.ToInt32(sr1, 2);
int num2 = Convert.ToInt32(sr2, 2);
int result = num1 & num2;
Use this if you want to get a binary string from the result.
BigInteger is the type you are looking for. It also have BitwiseOr.
If you really need to stick with strings it is not very hard to compute bitwise operations on character-by-character basis... but I'd avoid doing it if possible.
And here is a question on how to construct BigInteger from string of any base - BigInteger Parse Octal String?
var bitString = "10101";
BigInteger value = bitString.Aggregate(new BigInteger(), (b, c) => b * 2 + c - '0');
You have to convert the string to numbers first, you can use "Convert.ToInt32(String, Int32)", the second parameter lets you specify the base:
string sr1 = "0101110";
string sr2 = "1101110";
int one = Convert.ToInt32(sr1, 2);
int two = Convert.ToInt32(sr2, 2);
int result = one & two;
hope it helps.
You can't do bitwise operations on a string in the way you intend. There are interesting things you can do with bitwise operations on strings with other goals, like changing their case, but I think this is what you want:
// Convert the string to an integer
int foo = Convert.ToInt32(sr1, 2);
int bar = Convert.ToInt32(sr2, 2);
// Perform binary styff
int result = foo & bar;
// Convert back to a string, if you want
string resultStr = result.ToString();
I like Alexei's BigInteger solution, but it does require .NET 4.0 minimum. If for some reason you can't use that, then another option is to use the BitArray class, which has been available since .NET 1.1. Unfortunately, there is no method built-in to BitArray to parse a binary string, so you have to do that manually, similar to Alexei's solution.
Another option is a class I wrote called BoolArray which does a lot of the same things as BitArray, but does have a method to parse binary strings - use the static BoolArray.FromBinaryString method:
BoolArray bin = BoolArray.FromBinaryString("1001011000111010101"); // etc
Here is the BoolArray source code. Note, however, that it isn't quite complete, and isn't fully tested either, but I'm not immediately aware of any bugs.
EDIT: I noticed after pasting the original link that the code used a function provided in a different class of my "Utils" library, and wouldn't have compiled directly. I've updated the link to provide this class in the code as well... hopefully that was the only case, but if not let me know and I can fix.
I've made a function in C# to create a random string, but I wanted to convert it to VB.NET, unfortunately my knowledge of Visual Basic is much less than my knowledge of C#.
Here is my VB.NET function:
' Function will take in the number of characters in the string, as well as the optional parameter of chars to use in the random string
Private Function RandomString(ByVal Chars_In_String As Integer, Optional ByVal Valid_Chars As String = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM")
' Create a string to hold the resulting random string
Dim ReturnMe As String = ""
' Loop variable
Dim i As Integer = 0
' Run while loop while i is less than the desired number of Chars_In_String
While i < Chars_In_String
' Each time through, add to ReturnMe (selecting a random character out of the string of all valid characters)
ReturnMe += Valid_Chars(random.[Next](0, Valid_Chars.Length))
End While
' Return the value of ReturnMe
Return ReturnMe
End Function
' Create a new instance of the Random class, using a time-dependant default seed value
Dim random As New Random()
As you will see, its not much different from my C# version, except that since VB can take an optional parameter, I allow the user to select what characters to use in the string, or just use the default ones.
Here's the C# version of my function:
private static string RandomString(int Chars_In_String)
{
// Create a string to contain all valid characters (in this case, just letters)
string all = "qwertyuiopasdfghjklzxcvbnmQWERTYIOPASDFGHJKLZXCVBNM";
// Create a variable that will be returned, it will hold the random string
string ReturnMe = "";
// Run for loop until we have reached the desired number of Chars_In_String
for (int i = 0; i < Chars_In_String; i++)
{
// Each time through, add to ReturnMe (selecting a random character out of the string of all valid characters)
ReturnMe += all[random.Next(0, all.Length)];
}
// Return the value of ReturnMe
return ReturnMe;
}
// Create a new instance of the Random class, using a time-dependant default seed value
static Random random = new Random();
Again, there's not much different, but the part I'm really struggling on is the conversion between what is the 12th line of VB code, and the 13th line of C# code.
I didn't really know how to convert it to VB.NET (as I said, my knowledge of it is very limited), so I used an online converter. The result of the online converter runs with no errors, however when I try to call the function, no string appears.
In short, this C# code works fine:
ReturnMe += all[random.Next(0, all.Length)];
However, this VB.NET code doesn't work:
ReturnMe += Valid_Chars(random.[Next](0, Valid_Chars.Length))
How could I fix my VB.NET code?
There are a few issues in your function:
You're missing the increment of the while loop variable (this way the function fails with an OutOfMemoryException)
You shouldn't concatenate strings (even in the C# case). Use a StringBuilder instead.
This code should work
Private Shared Function RandomString(ByVal Chars_In_String As Integer, Optional ByVal Valid_Chars As String = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM") As String
Dim sb As StringBuilder = new StringBuilder()
Dim i As Integer = 0
Dim random As New Random()
While i < Chars_In_String
sb.Append(Valid_Chars(random.[Next](0, Valid_Chars.Length)))
i = i + 1
End While
Return sb.ToString()
End Function
It doesn't have anything to do with the string indexing operation, it is correct. You are simply forgetting to increment the loop counter. Use the For keyword:
Dim ReturnMe As String = ""
For i As Integer = 1 To Chars_In_String
ReturnMe += Valid_Chars(random.Next(0, Valid_Chars.Length))
Next
Return ReturnMe
A StringBuilder would be wise if Chars_In_String ever gets largish. Use the Shared keyword unless this code lives inside a Module.