|
Janded wrote: I am having problem setting up the variables. Do I have to store the age, pincode and numbers in int ?
You don't have to, you can store them in a string, which is how they come in from the user. However, if you what to do useful comparisons, then you do indeed need to convert them to int, long or similar.
The code below should give you the basics: Prompt, read in, convert, and show again.
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter your age:");
string userAge = Console.ReadLine();
int age;
if (int.TryParse(userAge, out age))
{
Console.WriteLine("In ten years you will be {0}", age + 10);
}
else
{
Console.WriteLine("{0} is not a number!", userAge);
}
}
} The TryParse examines a string and attempts to convert it to an int (in this case, long, double etc. are all available). There is also Parse, but that will throw an exception if the user enters "Hello" when you want a number. TryParse doesn't - it just returns false.You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
OriginalGriff wrote: However, if you what to do useful comparisons, then you do indeed need to convert them to int, long or similar.
Not really. If you want to compare two strings you can do so.
If you want to do some arithmetic (e.g. adding 10 to age) then you need to convert to a numeric.Regards
David R
---------------------------------------------------------------
"Every program eventually becomes rococo, and then rubble." - Alan Perlis
|
|
|
|
|
Picky, picky, picky!
I didn't want the OP to assume that string comparisons would be the most useful things he could do - and I believe in converting from string to more useful formats as early as possible, and converting back as late as possible. You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
Who voted you one for that? Perfectly reasonable comment, I thought. Balance redressed as best I can... You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
Your balancing caused a voting war
|
|
|
|
|
I don't really take any notice of the voting but thanks anyway.
My comment was triggered in part because I've seen horribly complex code to display the leading 0s when using numerics to store phone numbers and such like. All done in the name of saving a couple of bytes per record.
The worst was a warehouse management system (in VMS Basic) where store numbers in some files had three chars, some had integers, some longs, some four chars (with leading or trailing space) and one with six chars (commented 'For expansion'). So a simple comparison of store numbers in two files could not be done in one line. Regards
David R
---------------------------------------------------------------
"Every program eventually becomes rococo, and then rubble." - Alan Perlis
|
|
|
|
|
riced wrote: I don't really take any notice of the voting but thanks anyway.
Yeah, but a one vote implies to someone reading "this answer contains garbage" - since yours doesn't, I thought it should be corrected.
riced wrote: My comment was triggered in part because I've seen horribly complex code to display the leading 0s...
Don't you just love internal consistancy?
With telephone numbers I do tend to leave them as strings - there is no useful manipulation to do most of the time, and people do get protective of their favourite format: "+44 (0)1111 1111111" is "better" than "011111111111" and vice versa. If you can get a company wide format for these things, great - but too many will see that as the IT dept trying to "run their lives"! You can't win either way... You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
Most important question:
How are you comparing the variables?
Obviously the incoming data has to be string, and not so obviously the comparison values can be stored in any format you like, however the format should be picked dependant on the data contained. So integer for a pin number may be perfect, as long as you can only have integer pin numbers.
So, show us the comparison code and we can advise you further.
|
|
|
|
|
|
Firstly, all input from Console.ReadLine or from parameters passed to the exe are strings.
Secondly, in your code you are never capturing the input, and you have your logic back to front. For starters you never prompt for the age, and also you seem to refer to the name a lot, which is also never input.
Here is an example of how the code should start, showing the logic for the input and validation of the age. Apply the same locig throughout and you are home and dry.
int age;
string input;
Console.WriteLine("Please enter your age:");
input = Console.ReadLine();
if (!int.TryParse(input, out age)){
Console.WriteLine("{0} is not a number!", input);
Console.ReadLine();
return;
}
if (age < 18) {
Console.WriteLine("Sorry, Come back when your older");
Console.ReadLine();
return;
}
|
|
|
|
|
Can I use the technique below to ask a user for their security code as well. Assuming the scurity code is 2090, If the user enter a wrong code...a message comes up.
if (!int.TryParse(input, out code)){
Console.WriteLine("{0} is not a number!", input);
Console.ReadLine();
int code;
string codeInput;
I tried it using the technique above, but I had to press the enter key twice before I got any message from it
|
|
|
|
|
Can I use the technique below to ask a user for their security code as well. Assuming the scurity code is 2090, If the user enter a wrong code...a message comes up.
if (!int.TryParse(input, out code)){
Console.WriteLine("{0} is not a number!", input);
Console.ReadLine();
int code;
string codeInput;
or can I just do it this way int code = 2090;
I tried it using the technique above, but I had to press the enter key twice before I got any message from it
|
|
|
|
|
It will work if you use the same syntax as the example I gave you before.
The code you have posted is back-to-front and upside-down. You appear to be using the variables before you declare them. This is the same problem you had at the start, where you were testing the variables before inputing them!
|
|
|
|
|
Got it working, but I now need to enter numbers between 5 and 20 and print the users name requested the number of times.
This is what i intend to do..
Random random = new Random();
int randomNumber = random.next(5,20);
|
|
|
|
|
Or can I just say
int number;
number = int.Parse((console.Readline)); ?
|
|
|
|
|
i found a code segment to write new name/value pairs to app.config, but it doesn't work properly. means it doesn't change the app.config file permanently.
following is the code segment
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings.Add("name", t2.Text);
config.Save();
ConfigurationManager.RefreshSection("appSettings");
when i restart the program again only the default values are there .
any help,
|
|
|
|
|
If you are running your app from visual studio :
Not your app.config gets changed, in bin/<debug/release>-directory <YourAppName>.exe.config is altered.
|
|
|
|
|
Hi
What are the things i need to look into when i use serial port class?
My issue is I am getting a Timeout Exception every now and then in Reading the port.
My understanding about the serial port class is as below
1. We need to set the baud rate, parity etc once
2. Timeout value (read timeout and write timeout) every time you read or write.
a. Read timeout timer starts when the first characeter arrives at the hardware buffer and code will wait till all the characters arrived as per the code
comPort.Read(buffer, 0, 100); here it will wait for 100 bytes or timeout value whichever is earlier. ie. if it read 100 bytes it will return even if timeout (say 100mS) not reached. but what happens if there is lesser bytes? is there a interbyte timeout as in CPP here in C#? how to set it?
b. Write timeout functions in same fashion with writing to port. it will return after specified bytes have written unless timeout is not reached.
Am i correct in these assumptions?
Do I have to use some sort of thread locking in DataReceived event thread for proper displaying of the data? (I assume that the DataReceived event thread is system handled thread and does not have control over it. Am i correct?)
|
|
|
|
|
Message Closed
modified 23-Nov-14 6:35am.
|
|
|
|
|
Yes. I have set the port name, baudrate, parity, stopbit and databit. and my timeout is 100mS
stancrm wrote:
at this line will be hold for 2000ms.
If in 2000ms no data received, then TimeoutException.
Does this mean that the received data can be less than 100 bytes? That is if a single byte is received within the timeout period (in my case it is 100mS) there will be no timeout exception right?
One more thing is that I jump to this code only when System generates a DataRecieved event as in
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
SetTimeOuts(true);
byte[] buffer = new byte[101];
int iReadBufSize = comPort.Read(buffer, 0, 100);
string strData = String.Empty;
for (int i = 0; i < iReadBufSize; i++)
{
strData = strData + buffer[i].ToString() + " ";
}
DisplayRecievedData(buffer);
strData = "Rcd <<--: " + strData;
UpdateDisplayArea(strData);
SetTimeOuts(true);
}
catch (Exception exp)
{
MessageBox.Show("Exception in comPort_DataReceived()" + Environment.NewLine + exp.Message);
}
}
this event was registered like this when the serial port was created as
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
I observed that some times the byte[] buffer was null when I put break points there? Is it normal?
|
|
|
|
|
Message Closed
modified 23-Nov-14 6:34am.
|
|
|
|
|
My data is 30 to 60 byte long
My question is
Will the code return with first few byte immediately when it recevies the first event for DataRecieved? (because of slight inter-byte delays?)
Or it will go for reading and if found (it should... because event was generated) something in Hardware Buffer wait for the entire stream till there is no more bytes?
In both case there is no chance for timeouts
Is there any thing like "De register the event once it is served" ?
PS: I can not say when the data will be pushed from the other side so I need to be continuously monitoring the port. Is there any other method to do this than dataReceived event?
|
|
|
|
|
Deepak.Prahlad wrote: Is there any thing like "De register the event once it is served" ?
Yes - you can remove the handler in the same way you add them, but using -= instead of +=.
If for example it was a Timer event you would add with:
tim.Tick += new EventHandler(tim_Tick);
and remove it with:
tim.Tick -= tim_Tick;
You should never use standby on an elephant. It always crashes when you lift the ears. - Mark Wallace
C/C++ (I dont see a huge difference between them, and the 'benefits' of C++ are questionable, who needs inheritance when you have copy and paste) - fat_boy
|
|
|
|
|
Here is a nice Com Class that you can use.
using System;
using System.IO.Ports;
using System.Runtime.Remoting.Messaging;
using System.Drawing;
using System.Windows.Forms;
using System.Threading;
namespace ModemAPP
{
public class ComPorts
{
private const string ModuleName = "ComPorts";
internal static bool comPortExists;
internal static string[] myPortNames;
internal static string noComPortsMessage = "No COM ports found. Please attach a COM-port device.";
internal delegate void UserInterfaceDataEventHandler( string action, string formText, Color textColor );
internal static event UserInterfaceDataEventHandler UserInterfaceData;
internal delegate void UserInterfaceResultEventHandler(string strResult);
internal static event UserInterfaceResultEventHandler NumberCrunchInterface;
internal delegate void SerialDataReceivedEventHandlerDelegate( object sender, SerialDataReceivedEventArgs e );
internal delegate void SerialErrorReceivedEventHandlerDelegate( object sender, SerialErrorReceivedEventArgs e );
internal delegate bool WriteToComPortDelegate( string textToWrite );
internal delegate bool ReadComPortDelegate();
delegate void SetTextDeleg(string text);
internal WriteToComPortDelegate WriteToComPortDelegate1;
internal ReadComPortDelegate ReadComPortDelegate1;
private bool m_ParameterChanged;
private bool m_PortChanged;
private bool m_PortOpen;
private SerialPort m_PreviousPort = new SerialPort();
private int m_ReceivedDataLength;
private int m_SavedBitRate = 9600;
private Handshake m_SavedHandshake = Handshake.None ;
private string m_SavedPortName = "";
private SerialPort m_SelectedPort = new SerialPort();
internal bool ParameterChanged
{
get
{
return m_ParameterChanged;
}
set
{
m_ParameterChanged = value;
}
}
internal bool PortChanged
{
get
{
return m_PortChanged;
}
set
{
m_PortChanged = value;
}
}
internal bool PortOpen
{
get
{
return m_PortOpen;
}
set
{
m_PortOpen = value;
}
}
internal SerialPort PreviousPort
{
get
{
return m_PreviousPort;
}
set
{
m_PreviousPort = value;
}
}
internal int ReceivedDataLength
{
get
{
return m_ReceivedDataLength;
}
set
{
m_ReceivedDataLength = value;
}
}
internal int SavedBitRate
{
get
{
return m_SavedBitRate;
}
set
{
m_SavedBitRate = value;
}
}
internal Handshake SavedHandshake
{
get
{
return m_SavedHandshake;
}
set
{
m_SavedHandshake = value;
}
}
internal string SavedPortName
{
get
{
return m_SavedPortName;
}
set
{
m_SavedPortName = value;
}
}
internal SerialPort SelectedPort
{
get
{
return m_SelectedPort;
}
set
{
m_SelectedPort = value;
}
}
private SerialDataReceivedEventHandler SerialDataReceivedEventHandler1;
private SerialErrorReceivedEventHandler SerialErrorReceivedEventHandler1;
internal void CloseComPort( SerialPort portToClose )
{
try
{
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayStatus", "", Color.Black );
object transTemp0 = portToClose;
if ( !( transTemp0 == null ) )
{
if ( portToClose.IsOpen )
{
portToClose.Close();
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayCurrentSettings", "", Color.Black );
}
}
}
catch ( InvalidOperationException ex )
{
ParameterChanged = true;
PortChanged = true;
DisplayException( ModuleName, ex );
}
catch ( UnauthorizedAccessException ex )
{
ParameterChanged = true;
PortChanged = true;
DisplayException( ModuleName, ex );
}
catch ( System.IO.IOException ex )
{
ParameterChanged = true;
PortChanged = true;
DisplayException( ModuleName, ex );
}
}
internal void DataReceived( object sender, SerialDataReceivedEventArgs e )
{
string newReceivedData = null;
try
{
Thread.Sleep(200);
newReceivedData = SelectedPort.ReadExisting();
Thread.Sleep(100);
if (null != UserInterfaceData) UserInterfaceData("Dialing","",Color.Black);
if (newReceivedData.Length > 6)
{
if (null != UserInterfaceData) UserInterfaceData("RetrievingResults", "", Color.Black);
NumberCrunchInterface(newReceivedData);
}
}
catch (Exception ex)
{
DisplayException(ModuleName, ex);
}
}
private void DisplayException( string moduleName, Exception ex )
{
string errorMessage = null;
errorMessage = "Exception: " + ex.Message + " Module: " + moduleName + ". Method: " + ex.TargetSite.Name;
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayStatus", errorMessage, Color.Red );
}
private void ErrorReceived( object sender, SerialErrorReceivedEventArgs e )
{
SerialError SerialErrorReceived1 = 0;
SerialErrorReceived1 = e.EventType;
switch ( SerialErrorReceived1 )
{
case SerialError.Frame:
Console.WriteLine( "Framing error." );
break;
case SerialError.Overrun:
Console.WriteLine( "Character buffer overrun." );
break;
case SerialError.RXOver:
Console.WriteLine( "Input buffer overflow." );
break;
case SerialError.RXParity:
Console.WriteLine( "Parity error." );
break;
case SerialError.TXFull:
Console.WriteLine( "Output buffer full." );
break;
}
}
internal static void FindComPorts()
{
myPortNames = SerialPort.GetPortNames();
if ( myPortNames.Length > 0 )
{
comPortExists = true;
Array.Sort( myPortNames );
}
else
{
comPortExists = false;
}
}
internal bool OpenComPort()
{
bool success = false;
SerialDataReceivedEventHandler1 = new SerialDataReceivedEventHandler(DataReceived);
SerialErrorReceivedEventHandler1 = new SerialErrorReceivedEventHandler(ErrorReceived);
try
{
if ( comPortExists )
{
if ( PreviousPort.IsOpen )
{
CloseComPort( PreviousPort );
}
if ( ( !( ( SelectedPort.IsOpen ) ) | PortChanged ) )
{
SelectedPort.Open();
if ( SelectedPort.IsOpen )
{
SelectedPort.ReadTimeout = 20000;
SelectedPort.WriteTimeout = 20000;
SelectedPort.DataReceived += SerialDataReceivedEventHandler1;
SelectedPort.ErrorReceived += SerialErrorReceivedEventHandler1;
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayCurrentSettings", "", Color.Black );
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayStatus", "", Color.Black );
success = true;
PortChanged = false;
}
}
}
}
catch ( InvalidOperationException ex )
{
ParameterChanged = true;
PortChanged = true;
DisplayException( ModuleName, ex );
}
catch ( UnauthorizedAccessException ex )
{
ParameterChanged = true;
PortChanged = true;
DisplayException( ModuleName, ex );
}
catch ( System.IO.IOException ex )
{
ParameterChanged = true;
PortChanged = true;
DisplayException( ModuleName, ex );
}
return success;
}
internal void WriteCompleted( IAsyncResult ar )
{
WriteToComPortDelegate deleg = null;
string msg = null;
bool success = false;
msg = System.Convert.ToString( ar.AsyncState );
deleg = ( ( WriteToComPortDelegate )( ( ( AsyncResult )( ar ) ).AsyncDelegate ) );
success = deleg.EndInvoke( ar );
if ( success )
{
if ( null != UserInterfaceData ) UserInterfaceData( "UpdateStatusLabel", "", Color.Black );
}
}
internal void ReadComplete(IAsyncResult ar)
{
ReadComPortDelegate deleg = null;
string msg = null;
bool success = false;
msg = System.Convert.ToString(ar.AsyncState);
deleg = ((ReadComPortDelegate)(((AsyncResult)(ar)).AsyncDelegate));
success = deleg.EndInvoke(ar);
if (success)
{
if (null != UserInterfaceData) UserInterfaceData("UpdateStatusLabel", "", Color.Black);
}
Console.WriteLine("Write operation began: " + msg);
Console.WriteLine("Write operation succeeded: " + success);
}
internal bool WriteToComPort( string textToWrite )
{
bool success = false;
try
{
if ( ( !( ( SelectedPort == null ) ) ) )
{
if ( ( ( !( SelectedPort.IsOpen ) ) | PortChanged ) )
{
PortOpen = OpenComPort();
}
}
if ( SelectedPort.IsOpen )
{
SelectedPort.Write( textToWrite );
success = true;
}
}
catch ( TimeoutException ex )
{
DisplayException( ModuleName, ex );
}
catch ( InvalidOperationException ex )
{
DisplayException( ModuleName, ex );
ParameterChanged = true;
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayCurrentSettings", "", Color.Black );
}
catch ( UnauthorizedAccessException ex )
{
DisplayException( ModuleName, ex );
CloseComPort( SelectedPort );
ParameterChanged = true;
if ( null != UserInterfaceData ) UserInterfaceData( "DisplayCurrentSettings", "", Color.Black );
}
return success;
}
internal string ReadComPort()
{
bool success = false;
string dataReadToDisplay = null;
try
{
if ((!((SelectedPort == null))))
{
if (((!(SelectedPort.IsOpen)) | PortChanged))
{
PortOpen = OpenComPort();
}
}
if (SelectedPort.IsOpen)
{
dataReadToDisplay = SelectedPort.ReadLine();
success = true;
}
}
catch (TimeoutException ex)
{
DisplayException(ModuleName, ex);
}
catch (InvalidOperationException ex)
{
DisplayException(ModuleName, ex);
ParameterChanged = true;
if (null != UserInterfaceData) UserInterfaceData("DisplayCurrentSettings", "", Color.Black);
}
catch (UnauthorizedAccessException ex)
{
DisplayException(ModuleName, ex);
CloseComPort(SelectedPort);
ParameterChanged = true;
if (null != UserInterfaceData) UserInterfaceData("DisplayCurrentSettings", "", Color.Black);
}
return dataReadToDisplay;
}
}
}
|
|
|
|
|
Deepak.Prahlad wrote: Timeout value (read timeout and write timeout) every time you read or write
No, timeout is a property just like all others. You can set it once, it will hold its value.
Deepak.Prahlad wrote: Read timeout timer starts when the first characeter arrives at the hardware buffer
No, read timeout starts when a read operation starts. The behavior you are referring to exists in Windows but AFAIK is not exposed to the SerialPort class.
Deepak.Prahlad wrote: thread locking in DataReceived event
DataReceived is an asynchronous event; as such it is handled by a ThreadPool thread, which is not allowed to touch the Winform Controls directly. See this[^] and this[^] article.
One can never be sure that all the serial data that belongs together (a "message") will be received in one go; there always could be a hick-up somewhere, causing the message to be split over two DataReceived events. One approach that often leads to success is by having some delay between the start of the DataReceived event and the actual reading of the data.
|
|
|
|
|