How do i get cin.getline to timeout?

Please support our C++ advertiser: Intel Parallel Studio Home
Reply

Join Date: Jan 2008
Posts: 3
Reputation: sweRascal is an unknown quantity at this point 
Solved Threads: 0
sweRascal sweRascal is offline Offline
Newbie Poster

How do i get cin.getline to timeout?

 
0
  #1
Jan 17th, 2008
Hi all,
I am a novice c++ programmer with php experience and am trying to learn to do some usefull stuff in c++.
To learn I try to write a chat client with a mySQL backend and so far it works great.
To make it useable I need to get it to autorefresh the "screen" and show any new messages sent. As it is now I need to press ENTER to get it to refresh.

  1. // istream getline
  2. #include <iostream>
  3. #include "util.h"
  4. #include <mysql.h>
  5. #include "functions.h"
  6. #include <time.h>
  7. #include <windows.h>
  8.  
  9. //-------------------------------------------------------
  10. #define host "localhost"
  11. #define username "root"
  12. #define password ""
  13. #define database "chat"
  14. //-------------------------------------------------------
  15.  
  16. using namespace std;
  17.  
  18. int main () {
  19. MYSQL *conn;
  20. char message[256];
  21. char yourname[256];
  22. char sqlquery[255];
  23. char listquery[255];
  24. int seconds;
  25.  
  26. //mySQL
  27. conn = mysql_init(NULL);
  28. mysql_real_connect(conn,host,username,password,database,0,NULL,0);
  29. MYSQL_RES *res_set;
  30. MYSQL_ROW row;
  31. //-------
  32.  
  33. if (!mysql_real_connect(conn,host,username,password,database,0,NULL,0))
  34. {
  35. fprintf(stderr, "Failed to connect to database: Error: %s\n",
  36. mysql_error(conn));
  37. }
  38.  
  39. clrscr();
  40. cout << "Enter you alias: ";
  41. cin >> yourname;
  42.  
  43. while(strcmp (message,":q") != 0){
  44.  
  45. clrscr();
  46.  
  47. //mysql_query(conn,"SELECT * FROM chatlog");
  48. mysql_query(conn,"SELECT * FROM (SELECT * FROM chatlog ORDER BY datetime DESC LIMIT 22) t1 ORDER BY datetime ASC;");
  49. res_set = mysql_store_result(conn);
  50. while ((row = mysql_fetch_row(res_set)) != NULL)
  51. {
  52. //Konverterar UNIX time till human readable
  53. char buffer[32];
  54. time_t value = strtol(row[1], NULL, 10);
  55. struct tm *gmt = gmtime(&value);
  56. if ( gmt )
  57. {
  58. strftime(buffer, sizeof buffer, "%Y-%m-%d %X", gmt);
  59. }
  60. //-------------------------------------------
  61.  
  62. HANDLE hConsole;
  63. hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
  64.  
  65. SetConsoleTextAttribute(hConsole, 1);
  66. cout << "[" << buffer << "] - ";
  67. SetConsoleTextAttribute(hConsole, 2);
  68. cout << row[3] << " - ";
  69. SetConsoleTextAttribute(hConsole, 3);
  70. cout << row[2] << "\n";
  71. SetConsoleTextAttribute(hConsole, 6);
  72. }
  73.  
  74. cout << "-----------------------------------------------------------------------------";
  75. cout << "\nSay (:h for help): ";
  76.  
  77.  
  78. cin.getline (message,256,'\n');
  79.  
  80. if(strcmp (message,":h") == 0){
  81. clrscr();
  82. cout << "HELP\n";
  83. cout << ":q - Quit\n";
  84. cout << "\n";
  85. system("PAUSE");
  86. }else if(strcmp (message,":q") == 0){
  87. cout << "Quit!\n";
  88. return 0;
  89. }else if(strcmp (message,"\n") == 1){
  90. seconds = time (NULL);
  91. sprintf(sqlquery, "INSERT INTO chatlog (datetime, message,alias) VALUES ('%i','%s','%s')",seconds ,message,yourname);
  92. mysql_query(conn,sqlquery);
  93. printf("\n%ld Rader uppdaterade\n",
  94. (long) mysql_affected_rows(conn));
  95.  
  96. fprintf(stderr, "%s",
  97. mysql_error(conn));
  98. }
  99. }
  100.  
  101. mysql_close(conn);
  102. }

What I want is for the line
  1. cin.getline (message,256,'\n');

to timeout and simply put a "\n" in the message variable if nothing is typed within say 5 seconds.

Anyone has an idea on how to go about doing this?

BTW its great fun to program c++, especially with this great community helping.

Thx in advance
/sweRascal
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,740
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 739
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess

Re: How do i get cin.getline to timeout?

 
0
  #2
Jan 17th, 2008
>Anyone has an idea on how to go about doing this?
Yes, I have two that come to mind right away.

1) Create a new thread that asks for input. You can specify a timeout for the thread and wait for it in the main program. For example:
  1. #include <cstddef>
  2. #include <iostream>
  3. #include <windows.h>
  4.  
  5. struct data {
  6. char *buffer;
  7. std::size_t size;
  8. };
  9.  
  10. DWORD WINAPI get_input ( LPVOID arg )
  11. {
  12. data *buf = (data*)arg;
  13.  
  14. return !std::cin.getline ( buf->buffer, buf->size );
  15. }
  16.  
  17. int main()
  18. {
  19. char buffer[256] = {0};
  20.  
  21. data arg = {buffer, 256};
  22. HANDLE h;
  23. DWORD id;
  24.  
  25. h = CreateThread ( NULL, 0, get_input, &arg, 0, &id );
  26.  
  27. if ( h != NULL ) {
  28. if ( WaitForSingleObjectEx ( h, 5000, FALSE ) == WAIT_TIMEOUT ) {
  29. std::cout<<"Timeout\n";
  30. buffer[0] = '\n';
  31. }
  32.  
  33. std::cout<<"buffer: \""<< buffer <<"\"\n";
  34.  
  35. CloseHandle ( h );
  36. }
  37. }
2) Don't use getline. Instead, take input character by character using a non-blocking read and use your own timer. This essentially duplicates the thread solution manually without using threads, but it's still non-portable. For example:
  1. #include <cstddef>
  2. #include <ctime>
  3. #include <iostream>
  4. #include <conio.h>
  5.  
  6. bool get_input ( char *buffer, std::size_t size, int timeout )
  7. {
  8. std::time_t start = std::time ( 0 );
  9. std::size_t n = 0;
  10.  
  11. for ( ; ; ) {
  12. if ( n == 0 && std::difftime ( std::time ( 0 ), start ) >= timeout )
  13. return false;
  14.  
  15. if ( kbhit() ) {
  16. if ( n == size - 1 )
  17. break;
  18.  
  19. char ch = (int)getche();
  20.  
  21. if ( ch == '\r' ) {
  22. buffer[n++] = '\n';
  23. break;
  24. }
  25. else
  26. buffer[n++] = ch;
  27. }
  28. }
  29.  
  30. buffer[n] = '\0';
  31.  
  32. return true;
  33. }
  34.  
  35. int main()
  36. {
  37. char buffer[256] = {0};
  38.  
  39. if ( !get_input ( buffer, 256, 5 ) ) {
  40. std::cout<<"Timeout\n";
  41. buffer[0] = '\n';
  42. }
  43.  
  44. std::cout<<"buffer: \""<< buffer <<"\"\n";
  45. }
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Reply

This thread is more than three months old.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC