The desktop client we use with our phone system has an API which allows us to capture the telephone number of the phone as it rings.
In order to use the API you reference a DLL and specify.
using TelephonyProxy;
public class program
{
private static Commander commander;
private static Listener listener;
static void Main()
{
commander = new Commander();
listener = new Listener();
SubscribeToListener();
}
private static void SubcribeToListener()
{
Debug.WriteLine("Subscribe To Listener");
listener.Connect += OnConnect;
listener.Disconnect += OnDisconnect;
listener.Offering += OnOffering;
listener.Ringback += OnRingback;
}
private static void OnOffering(string name, string number)
{
Debug.WriteLine(number + “abc”);
}
}
The issue is the OnOffering is called correctly and the telephone number is in the number variable. However the debug only shows the number and not the “abc”. In testing it seems you can concatenate anything in front of number but anything after is ignored.
Have you any idea why that might be?
Thanks for any input you can give this.
ASCII character 0 (represented in the debugger as \0) is sometimes used to terminate strings. If you're dealing with something like a COM device, etc., this may be the case.
For example:
Debug.WriteLine("a\0b");
will only output "a". ASCII character 0 is not printed, nor are any of the subsequent characters. Naturally, appending something to such a string will mean that anything after \0 in the original string, nothing will appear.
If you're dealing with COM, look at the string in the debugger and see if \0 is on the end.
You could remove it using replace:
Debug.WriteLine(number.Replace("\0", "") + "abc");
Related
Greeting fellow programmers!
I am currently studying software development (I started not a month ago) and I have a problem that needs a solution. Underneath you can find the code and as you can see, the method WriteNumber needs help. I need to write the code in a way that when I run the program, on the console screen the following two lines will be shown:
Hello World!
81
The Main method code cannot be changed and also I cannot add more methods to the class Calculator so the code needs to be done only within the WriteNumbers method. I have tried a lot of things but I am still grasping how everything works so any help is welcome! Thank you in advance for your time.
Namespace CalculatorTest
{
class Calculator
{
public static string WriteText (string input)
{
return "" + input;
}
public static string WriteNumber()
{
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28);
Console.WriteLine(n);
Console.Read();
}
}
Not to do your homework for you to just be copied/pasted, hopefully I can give you some hints...
Notice how the method is being invoked:
Calculator.WriteNumber(53 + 28)
The 53 + 28 part happens first, then the result of that operation is passed to the method. That result, naturally, is 81. What's important about that is its type, which is an integer.
So, reasonably, the method signature needs to accept an int as a parameter. This would be done very similarly to how the other method accepts a string as a parameter:
public static string WriteText(string input)
What, then, does that method need to do with that input? Well, it's only a single value, so there aren't any calculations to be performed on it. It would appear that the method simply needs to return the value as a string. (It's your homework so you tell me, is that correct?)
This can be done with exactly two things:
Calling .ToString() on the value
Using the return keyword to return the result of that operation
(Note: The .ToString() operation does something very intuitive on value types, such as int or double or bool. As you progress into using reference types, you're going to find that it does something very different. Any time you have a custom class on which you want to call .ToString(), you'll need to override the .ToString() method on that class first.)
Please read David's answer, it's important that you make the effort to understand why this works the way it does. That being said:
public static string WriteNumber(int number)
{
return number.ToString();
}
Thank you all for your valuable input but special thanks to David because he showed where I made my error. I forgot that the two numbers in the main function will be summed up FIRST and THEN forwarded to the method in the class Calculator. After that got cleared up, it was easy to understand what to do (basically adjust the type of the input parameter to int).
namespace CalculatorTest
{
class Calculator
{
public static string WriteText (string input)
{
return "" + input;
}
public static string WriteNumber(int sumOfNumbers)
{
return "" + sumOfNumbers;
}
}
class Program
{
static void Main(string[] args)
{
string s = Calculator.WriteText("Hello World!");
Console.WriteLine(s);
string n = Calculator.WriteNumber(53 + 28);
Console.WriteLine(n);
Console.Read();
}
}
}
so I'm writing a program that takes in a text line by line and then is supposed to output yes or no if the line contains the word problem.
The program is working, but I have to press enter twice to get the output.
The first enter I get, which is for the last line. And the second enter is so the while loop can break out.
Any suggestions to how I can improve this and not need the second enter?
using System;
using System.Collections.Generic;
namespace Tester
{
internal class Program
{
private static void Main(string[] args)
{
List<string> stringList = new List<string>();
string input = "";
while ((input = Console.ReadLine()) != string.Empty)
{
var s = input.ToLower();
stringList.Add(s.Contains("problem") ? "yes" : "no");
}
foreach (var str in stringList)
Console.WriteLine(str);
Console.ReadKey();
}
}
}
Well, for the last output you will type something. That's when (input = Console.ReadLine()) != string.Empty kicks in and the condition will pass.
The loop will come back to this line and block until you give it new input. Then supposedly you just type enter and in that case the loop will just exist. This is expected behaviour.
I'm not sure what upsets you about this. If you reaaaally wanted to get rid of the second enter, maybe you can put some token in your line (line /q or whatever) and whenever that is found in your line you know that you should break out of the loop.
Alternatively you can count how many inputs you get and make sure you get exactly 10 or 20 or whatever. When that number is reached, the loop will exit after the last input is processed.
Welcome to SO. :)
You can safely get rid of the last ReadKey. Given that you're creating a console application, you would normally rut it... in a console - as such, consoles don't close themselves after a program is done running. It's different if you run a console application in Windows OUTSIDE of a console - in this case, Windows will open a temporary console, run the app, and then close the console.
Also, if you're using Visual Studio, you can make VS wait for you by using the "start without debug" option (Ctrl+F5). VS will then add a "press enter to close" on it's own, at the end, to prevent the window from closing too fast, allowing you to check your outputs / exceptions.
One simple solution could be to output the "yes" or "no" values per line, rather than all at once at the end of your app.
Another way (which would require a bit more coding) would be to read individual keys, rather than lines - then you could react to the user pressing Esc, for example, rather than relying on an empty string ("extra" enter press).
You can use string.IsNullOrEmpty() and ToUpper() method is in general more accurate than ToLower(). So i'd probably refactor your code to something like :
private static void Main(string[] args)
{
List<string> stringList = new List<string>();
string input = "";
while(!string.IsNullOrEmpty(input = Console.ReadLine()))
stringList.Add(input.ToUpper().Contains("PROBLEM") ? "yes" : "no");
foreach (var str in stringList)
Console.WriteLine(str);
Console.ReadKey();
}
By the way welcome to SO... ;)
ok,do you mean this
static void Main(string[] args)
{
string input = "";
input = Console.ReadLine();
while (input != string.Empty)
{
if (input.Contains("problem"))
{
Console.WriteLine("yes");
}
else
{
Console.WriteLine("no");
}
input = Console.ReadLine();
}
Console.ReadKey();
}
maybe I know your intention.But if you want to break the while(input!=string.Empty) you must press an empty line.
I have a list filed with data which I have already set up like so:
public List<string> stringValues = new List<string>();
void Start()
{
stringValues.Add( "D5B51D14-9ED8-1530-5455-CFF2C4B86151");
stringValues.Add( "335B8649-AB22-E146-05A0-E9A4F3813A1F");
stringValues.Add( "28797BB5-9020-C0B5-F0CE-72AB7F1830E2");
stringValues.Add( "CD377141-422D-E8B0-B845-A0AF408E565A");
stringValues.Add( "DEEE65FB-FF1F-A6A9-4C3C-5784F41B0D39");
stringValues.Add( "70489FFA-6C88-A40D-C615-FD1EDEBD7643");
}
I also have a method which reads in data being sent in from a device and displays it on the screen. I've had to cut a chop bits off of the string to make sure I only get the data I want, to appear on the screen.
This is what the method looks like:
private void AppendString(string message)
{
int startIndex = 38;
int endIndex = 36;
message = message.Substring(startIndex,endIndex);
messageCount = "length is " + message.Length.ToString();
outputContent.text += "\n" + message;
}
The thing is, the data getting sent into my program is something I have no idea about. It could contain anything. What I'm needing my program to do is check the portion of the string I need and compare the value it finds against those in my list. Then, should the list contain the same data, do something.
How can I go about comparing my list against data that is dynamically getting passed into it with my code above?
edit
I'll explain the appendMessage function a bit more and why it is like that:
the devices Im reading in send out data in the following way:
<CBPeripheral: 0xda4bab0 identifier = D5B51D14-9ED8-1530-5455-CFF2C4B86151, Name = "estimote", state = connecting>
Most of that is fine, but the only part I'm caring about is the long number held in the identifier portion of the line. In my program when I run the app, instead of displaying that entire line, the only part it puts out is that number there. Nothing else.
So, having chopped up that line, I'm storing in a UILabel (unity gui string) called outputContent and I'm accessing the data held in it when by calling outputContent.text
Which, when combined with the sample answer given below, my list check looks like this:
if(stringValues.Contains(outputContent.text))
{
Instantiate(estimote6Model, new Vector3(2.5f,0.7f,0), Quaternion.identity);
uuidString = "got an estimote 6";
}
However, whilst the string on display is the part of the line I want, nothing happens and I'm still trying to work out why.
You can search if the list with the method .Contains(). So something like this:
if (stringValues.Contains(message))
{
// do something
}
You can add this snipped at the end of your AppendString() method, because there, the variable message should hold the id's, which could be part of the stringValues list, right?
If you don't want to check for this within the AppendString() method, you must store your id's from the device in a separate list:
public List<string> deviceValues = new List<string>();
private void AppendString(string message)
{
int startIndex = 38;
int endIndex = 36;
message = message.Substring(startIndex,endIndex);
messageCount = "length is " + message.Length.ToString();
outputContent.text += "\n" + message;
deviceValues.Add(message); // add here the input from the device
}
Then you can check if stringValues contains any of the values from deviceValues with:
if (stringValues.Any(x => deviceValues.Contains(x)))
{
// do something
}
I am receiving from a serial port (vhf receiver) some data from different sources lets say for example cars. The whole program at the moment is a while loop. While the port is open i am receiving bytes in arrays and do some decoding. Every cycle of the while loop 1 message is received and decoded. But in one case there is a message that is split in to parts an odd part and an even part. I need both to decode the message but only one part is received in 1 while cycle lets say the oddpart from car1. The next while cycle may contain oddpart from car2 or evenpart from car1 or evenpart from car3 etc. So i need a way to store the odd even parts of each car until both of them are received. And another important thing: there should be a 10 seconds time window from the moment i receive the first part until the moment i recieve the second part. If 10seconds pass the first part should be descarded. I guess arrays wont work because i need something dynamic like a List or a dictionary.
while (serialportopen)
{
//somedecoding I end up with
string hexid;
string oddpart;
string evenpart;
}
I tried creating a class like this with properties to hold the message parts but i cant create an object with the name hexid because it is already declared. Any ideas including lists dictionaries or classes?
The way most systems do it, when dealing with variable length data segments, is there's something unique about the first packet that comes through, that notifies the receiving driver that it's two part. For example, it might simply be the MSB (most significant bit) set or unset on the first packet, where 0 could denote that there is no second packet, and 1 could denote that there is a second packet. Then it's simply a matter of masking it when y you get it, and calling a function to receive the second part, or setting a flag that the second part needs to be received, and that it's NOT a new packet.
As for the scope, I'm kind of foggy on what you're asking, but based on the code above, if you declare the variables outside the loop, ie.:
string hexid;
string oddpart;
string evenpart;
while (serialportopen)
{
}
They'll maintain scope for multiple iterations of the loop. It's better to do it that way regardless, as it won't re-declare the variable each time. That may or may not be optimized out by the compiler.
Otherwise there's something uniqe about the bit pattern of that packet that notifies the driver that another packet is needed. There may be an opcode or command field in that packet, it may be simply an issue of masking that, calling on a function to retrieve and return the second part, ie.
if ((command & CERTAIN_PACKET) == CERTAIN_PACKET)
odpart = GetSecondPart();
I hope that helps you some!
I understand that you have a way to telle an odd part from an even part, from a complete id, and that you have a way to tell the origin of your message. In this case I would store the oddparts (if they are always the ones that are received first) in a dictionary. When I receive an even part I would check to see if there is its corresponding odd part stored and if this is the case I would process the whole thing, otherwise I would discard it. Furthermore, when I receive an odd part I would start a timer responsible for deleting it from the dictionary after 10 seconds are passed. Since the timer has to be stopped, it will be stored in a dictionary, too. Something like this (it's only an example, probably you'd want to create some instance variables to avoid passing parameters everywhere):
Dictionary<string, string> oddParts = new Dictionary>string, string>();
Dictionary<string, Timer> timers = new Dictionary<string, Timer>();
while (serialportopen)
{
// somedecoding I end up with
string hexid;
string oddpart;
string evenpart;
// you need something to identify where the message came from and that is present in both the odd and even part (the BF... of your previous question)
string msgId;
if (!String.IsNullOrEmpty(oddpart))
ProcessOddPart(msgId, oddpart, oddParts, timers);
else if (!String.IsNullOrEmpty(evenpart))
hexid = HexIdFromEvenPart(msgId, evenpart, oddparts, timers);
if (!String.IsNullOrEmpty(hexid))
Process(hexid);
}
void Process(string hexid)
{
// your stuff here
}
void ProcessOddPart(string msgId, string oddPart, Dictionary<string, string> oddParts, Dictionary<string, Timer> timers)
{
oddParts[msgId] = oddPart;
System.Timers.Timer tmr = new Timer();
timers[msgId = tmr;
ElapsedEventHandler timePassed = delegate(object anObj, ElapsedEventArgs args) {
tmr.Stop();
oddParts.Remove(msgId);
timers.Remove(msgId);
};
tmr.Interval = 10000;
tmr.Elapsed += timePassed;
tmr.Start();
}
void HexIdFromEvenPart(string msgId, string evenPart, Dictionary<string, string> oddParts, Dictionary<string, Timer> timers)
{
string oddPart;
Timer tmr;
if (timers.TryGetValue(msgId, out tmr))
{
tmr.Stop();
timers.Remove(msgId);
}
if (!oddParts.TryGetValue(msgId, out oddPart))
return null;
return oddPart + evenPart;
}
In C#, getting command line arguments directly from Main() omits the exe name, contrary to the tradition of C.
Getting those same command line args via Environment.GetCommandLineArgs includes it.
Is there some good logical reason I'm missing for this apparent inconsistency?
class Program
{
static void Main(string[] args)
{
Console.WriteLine(string.Format("args.Length = {0}", args.Length));
foreach(string arg in args)
{
Console.WriteLine(string.Format("args = {0}", arg));
}
Console.WriteLine("");
string[] Eargs = Environment.GetCommandLineArgs();
Console.WriteLine(string.Format("Eargs.Length = {0}", Eargs.Length));
foreach (string arg in Eargs)
{
Console.WriteLine(string.Format("Eargs = {0}", arg));
}
}
}
Output:
C:\\ConsoleApplication1\ConsoleApplication1\bin\Debug>consoleapplication1 xx zz aa
args.Length = 3
args = xx
args = zz
args = aa
Eargs.Length = 4
Eargs = consoleapplication1
Eargs = xx
Eargs = zz
Eargs = aa
Because it isn't C and thus isn't tied to it's conventions. Needing the exe name is pretty much an edge case; the small number of times I've needed this (compared to the other args) IMO justifies the decision to omit it.
This is additionally demanded in the spec (ECMA334v4, §10.1); (snipping to relevant parts):
10. Basic concepts
10.1 Application startup
...
This entry point method is always named Main, and shall have one of the
following signatures:
static void Main() {…}
static void Main(string[] args) {…}
static int Main() {…}
static int Main(string[] args) {…}
...
• Let args be the name of the parameter. If the length of the array designated by args is greater than
zero, the array members args[0] through args[args.Length-1], inclusive, shall refer to strings,
called application parameters, which are given implementation-defined values by the host environment
prior to application startup. The intent is to supply to the application information determined prior to
application startup from elsewhere in the hosted environment. If the host environment is not capable of
supplying strings with letters in both uppercase and lowercase, the implementation shall ensure that the
strings are received in lowercase. [Note: On systems supporting a command line, application, application parameters
correspond to what are generally known as command-line arguments. end note]
[status-by-design] -- http://msdn.microsoft.com/en-us/library/acy3edy3(v=VS.100).aspx
Unlike C and C++, the name of the program is not treated as the first command-line argument.
To me, the reason the two methods return different results is due to Context.
The Environment class is used to manipulate the current environement and process, and it makes sense that Environment.GetCommandLineArgs(); returns the executable name, since it is part of the process.
As for the args array, to me it makes sense to exclude the executable name. I know that I am calling the executable and in the context of running my application I want to know what arguments were sent to it.
At the end of the day, it is powerful to have a way to get at both alternatives.