Reputation: 125
I am trying to write to the Standard Input of a Process (a C++ program) in C#. The problem is that the C++ program seems to not be able to read what I write from my C# app. Here are both of the programs:
// C#
static void Main(string[] args) {
Console.InputEncoding = Encoding.Unicode;
Console.OutputEncoding = Encoding.Unicode;
Process CoutN = new Process();
CoutN.StartInfo.FileName = @"C:\Users\Vesk\Desktop\CoutN.exe";
CoutN.StartInfo.UseShellExecute = false;
CoutN.StartInfo.RedirectStandardInput = true;
CoutN.StartInfo.RedirectStandardOutput = false;
CoutN.Start();
CoutN.StandardInput.WriteLine("5");
CoutN.WaitForExit();
Console.ReadKey();
}
// C++
int main() {
int n;
std::cin >> n;
std::cout << "N is " << n << std::endl;
return 0;
}
Here is the output from my C# program: N is 0
. It should instead be N is 5
.
From what I could understand the encoding that C# uses for a Process's Input/Output Stream is the same as the one used by the Console. Here's the thing though, in my C# program I'll need to be able to use the Console to input cyrillic text (as well as other non-ASCII text). The only Console Encoding which seems to work for that is Encoding.Unicode
(which apparently is just UTF-16 LE).
But it seems that when I try to write to the Process's Input Stream, it just can't understand that and it outputs N is 0
for some reason. From what I understand this is because UTF-16 is not compatible with ASCII (or whatever the C++ iostream
expects).
So is there a way to actually change the Encoding that the Process's Standard Input uses?
Here is what I have tried/cannot try:
iostream
(cin
, cout
). (Edit for clarification: My C# program will only ever need to "send" ASCII text to the C++ program)Encoding.ASCII
and it worked. It also worked if I just left the Console at it's default Encoding. But again this will not work for me, because these encodings don't seem to work with Cyrillic.Encoding.UTF8
and that didn't work, although I wouldn't have been able to use that anyway, because it doesn't seem to work with Cyrillic text in my C# app.CoutN.StandardInput.Encoding
, but unfortunately it is a read-only property.CoutN.StandardOutput.ReadToEnd()
and it works and the output from the C++ program is read correctly (still says N is 0
though). But for some reason the Standard Input is different.5
in the C# program's Console and the output was N is 5
.StreamWriter
with a different encoding and write from there:StreamWriter str = new StreamWriter(CoutN.StandardInput.BaseStream, Encoding.ASCII);
str.WriteLine("5");
But this didn't work either. I even tried basically all the Encodings and even no Encoding, but nothing worked.
BaseStream
myself:byte[] buffer = Encoding.ASCII.GetBytes("5");
CoutN.StandardInput.BaseStream.Write(buffer, 0, buffer.Length);
CoutN.StandardInput.WriteLine();
And that didn't work.
At this point I feel like I've exhausted all the options that I could try. Any help is appreciated, thanks in advance!
Upvotes: 0
Views: 1184
Reputation: 13864
You don't get to chose what encoding the other process is using from your own code - if you're sending input to the standard input stream of an application that is expecting a specific encoding, then short of it having some setting to change that there's nothing you can do about it.
If you're interacting with the STDIO streams of another application, you are expected to match whatever encoding it is expecting, rather than the other way around. The encoding of the console doesn't really matter except in cases where the application inherits its encoding from the environment.
Indeed, if you're trying to use an encoding that supports Cyrillic characters, then the receiving application must have been designed to accommodate this. If the application was written by someone whose native character set only uses Latin characters then they may well have never bothered to do this. It's part of the reason for the push to adopt UTF8 everywhere since then you don't really need to think about it too much.
Edit: If you're trying to match the expected input encoding, then you do it thusly:
Process.StandardInput.Write(Encoding.ASCII.GetBytes("My String Here\r\n"));
Replacing Encoding.ASCII
with whatever character set applies to get the appropriate GetBytes()
method.
Note that the ASCII character set specifically does not include Cyrillic characters, so it's impossible to use them in an application that expects ASCII. If it expects some other character set that does support them then you're fine. Cyrillic uses Codepage 855 or needs UTF8.
Upvotes: 1