Saving randomly generated passwords to a text file in order to display them later - c++-cli

I'm currently in a traineeship and I currently have to softwares I'm working on. The most important was requested yesterday and I'm stucked on the failure of its main feature: saving passwords.
The application is developped in C++\CLR using Visual Studio 2013 (Couldn't install MFC libraries somehow, installation kept failing and crashing even after multiple reboots.) and aims to generate a password from a seed provided by the user. The generated password will be save onto a .txt file. If the seed has already been used then the previously generated password will show up.
Unfortunately I can't save the password and seed to the file, though I can write the seed if I don't get to the end of the document. I went for the "if line is empty then write this to the document" but it doesn't work and I can't find out why. However I can read the passwords without any problem.
Here's the interresting part of the source:
int seed;
char genRandom() {
static const char letters[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(letters) - 1;
return letters[rand() % stringLength];
}
System::Void OK_Click(System::Object^ sender, System::EventArgs^ e) {
fstream passwords;
if (!(passwords.is_open())) {
passwords.open("passwords.txt", ios::in | ios::out);
}
string gen = msclr::interop::marshal_as<std::string>(GENERATOR->Text), line, genf = gen;
bool empty_line_found = false;
while (empty_line_found == false) {
getline(passwords, line);
if (gen == line) {
getline(passwords, line);
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(line);
break;
}
if (line.empty()) {
for (unsigned int i = 0; i < gen.length(); i++) {
seed += gen[i];
}
srand(seed);
string pass;
for (int i = 0; i < 10; ++i) {
pass += genRandom();
}
passwords << pass << endl << gen << "";
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(pass);
empty_line_found = true;
}
}
}
I've also tried replacing ios::in by ios::app and it doesn't work. And yes I have included fstream, iostream, etc.
Thanks in advance!
[EDIT]
Just solved this problem. Thanks Rook for putting me on the right way. It feels like a silly way to do it, but I've closed the file and re-openned it using ios::app to write at the end of it. I also solved a stupid mistake resulting in writing the password before the seed and not inserting a final line so the main loop can still work. Here's the code in case someone ends up with the same problem:
int seed;
char genRandom() {
static const char letters[] =
"0123456789"
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz";
int stringLength = sizeof(letters) - 1;
return letters[rand() % stringLength];
}
System::Void OK_Click(System::Object^ sender, System::EventArgs^ e) {
fstream passwords;
if (!(passwords.is_open())) {
passwords.open("passwords.txt", ios::in | ios::out);
}
string gen = msclr::interop::marshal_as<std::string>(GENERATOR->Text), line, genf = gen;
bool empty_line_found = false;
while (empty_line_found == false) {
getline(passwords, line);
if (gen == line) {
getline(passwords, line);
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(line);
break;
}
if (line.empty()) {
passwords.close();
passwords.open("passwords.txt", ios::app);
for (unsigned int i = 0; i < gen.length(); i++) {
seed += gen[i];
}
srand(seed);
string pass;
for (int i = 0; i < 10; ++i) {
pass += genRandom();
}
passwords << gen << endl << pass << endl << "";
PASSWORD->Text = msclr::interop::marshal_as<System::String^>(pass);
empty_line_found = true;
}
}
passwords.close();
}

So, here's an interesting thing:
passwords << pass << endl << gen << "";
You're not ending that with a newline. This means the very end of your file could be missing a newline too. This has an interesting effect when you do this on the final line:
getline(passwords, line);
getline will read until it sees a line ending, or an EOF. If there's no newline, it'll hit that EOF and then set the EOF bit on the stream. That means the next time you try to do this:
passwords << pass << endl << gen << "";
the stream will refuse to write anything, because it is in an eof state. There are various things you can do here, but the simplest would be to do passwords.clear() to remove any error flags like eof. I'd be very cautious about accidentally clearing genuine error flags though; read the docs for fstream carefully.
I also reiterate my comment about C++/CLR being a glue language, and not a great language for general purpose development, which would be best done using C++ or a .net language, such as C#. If you're absolutely wedded to C++/CLR for some reason, you may as well make use of the extensive .net library so you don't have to pointlessly martial managed types back and forth. See System::IO::FileStream for example.

Related

Making cin take selective inputs [Turbo C++]

Don't hate cause of Turbo, I already hate my school!
I wish to show an error msg if a character is entered instead of an int or float in some file such as age or percentage.
I wrote this function:
template <class Type>
Type modcin(Type var) {
take_input: //Label
int count = 0;
cin>>var;
if(!cin){
cin.clear();
cin.ignore();
for ( ; count < 1; count++) { //Printed only once
cout<<"\n Invalid input! Try again: ";
}
goto take_input;
}
return var;
}
but the output is not desirable:
How do I stop the error msg from being repeated multiple times?
Is there a better method?
NOTE: Please make sure that this is TurboC++ that we are talking about, I tried using the approach in this question, but even after including limits.h, it doesn't work.
Here, a code snippet in C++.
template <class Type>
Type modcin(Type var) {
int i=0;
do{
cin>>var;
int count = 0;
if(!cin) {
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(), '\n');
for ( ; count < 1; count++) { //Printed only once
cout<<"\n Invalid input! Try again: ";
cin>>var;
}
}
} while (!cin);
return var;
}
The variables are tailored to match yours' so you can understand better. This code isn't perfect though.
It can't handle cases like "1fff", here you would just get a 1 in return. I tried solving it but then a infinite loop was being encountered, when I'll fix it, I'll update the code.
It also can't function in TurboC++ effectively. I don't know if there are alternatives but the numeric_limits<streamsize>::max() argument gives a compiler error ('undefined symbol' error for numeric_limits & streamsize and 'prototype must be defined' error for max()) in Turbo C++.
So, to make it work in Turbo C++. Replace the numeric_limits<streamsize>::max() argument with some big int value such as 100.
This will make it so that the buffer is only ignored/cleared till 100 characters are reached or '\n' (enter button/newline character) is pressed.
EDIT
The following code can be executed on both Turbo C++ or proper C++. The comments are provided to explain the functioning:
template <class Type> //Data Integrity Maintenance Function
Type modcin(Type var) { //for data types: int, float, double
cin >> var;
if (cin) { //Extracted an int, but it is unknown if more input exists
//---- The following code covers cases: 12sfds** -----//
char c;
if (cin.get(c)) { // Or: cin >> c, depending on how you want to handle whitespace.
cin.putback(c); //More input exists.
if (c != '\n') { // Doesn't work if you use cin >> c above.
cout << "\nType Error!\t Try Again: ";
cin.clear(); //Clears the error state of cin stream
cin.ignore(100, '\n'); //NOTE: Buffer Flushed <|>
var = modcin(var); //Recursive Repeatation
}
}
}
else { //In case, some unexpected operation occurs [Covers cases: abc**]
cout << "\nType Error!\t Try Again: ";
cin.clear(); //Clears the error state of cin stream
cin.ignore(100, '\n'); //NOTE: Buffer Flushed <|>
var = modcin(var);
}
return var;
//NOTE: The '**' represent any values from ASCII. Decimal, characters, numbers, etc.
}

File input not working

I have this C++ program that will get key code and store it as a string in a text file. After I run the program the file is supposed to appear alongside my cpp file but I doesn't appear. I think is got to do with the Save function where the file input and output is happening. Does anyone notices any errors(I get none while compiling).
#include <iostream>
#include <Windows.h>
#include <Winuser.h>
#include <fstream>
using namespace std;
int Save (int Key_Stroke, char *file);
int main(){
char i;
while(1){
for(i = 8; i <= 190; i++){
if(GetAsyncKeyState(i) == -32767){
Save(i, "LOG.TXT");
}
}
}
system("PAUSE");
return 0;
}
int Save (int Key_Stroke, char *file){
if((Key_Stroke == 1) || (Key_Stroke == 2) || (Key_Stroke == 5))
return 0;
FILE *OUTPUT_FILE;
OUTPUT_FILE = fopen(file, "a+");
fprintf(OUTPUT_FILE, "%s", &Key_Stroke);
fclose(OUTPUT_FILE);
cout << Key_Stroke << endl;
return 0;
}
When using C fprintf (this isn't typically used in C++, see ofstream) you don't use reference operator & because you are passing value to function, not address. Also formatting string is wrong, you want to write int %d, not array of chars %s (more here)
Your Save function should look like
int Save(int Key_Stroke, const char *file)
{
if((Key_Stroke == 1) || (Key_Stroke == 2) || (Key_Stroke == 5))
return 0;
FILE *OUTPUT_FILE = fopen(file, "a+");
if(OUTPUT_FILE != NULL)
{
fprintf(OUTPUT_FILE, "%d", Key_Stroke);
fclose(OUTPUT_FILE);
}
cout << Key_Stroke << endl;
return 0;
}
Also notice const keyword in second argument of the function. This should be used to avoid writing to constant area of memory - directly written array of chars "LOG.TXT" .
Next thing, you should always check if the file you are trying to write to is correctly opened if(OUTPUT_FILE != NULL) .

OpenNI2+Nite2 isNew() isLost() methods in Kinect SDK

I recently switched from OpenNI2+Nite2 confuguration to official Kinect SDK for a project. In nite my code goes like this:
const nite::Array<nite::UserData>& users = frame.getUsers();
for (int i=0; i<users.getSize(); i++){
const nite::UserData& user = users[i];
if(user.isNew()){/* do this */}
if(user.isLost()){/* do that */}
else {/* update*/}
However, I couldn't find a method that does the same thing as isNew & isLost in Kinect SDK. I implemented my own method for isNew, but I failed in isLost.
// handle user exit
map<string,Group3D*> g3D_copy = g3D;
for(map<string,Group3D*>::iterator mit = g3D_copy.begin();mit != g3D_copy.end();mit++){
if(mit->second->getType() == "KINECT_SKELETON")
{
string groupID = mit->first;
int countExistance2 = 0;
for (int i = 0; i < NUI_SKELETON_COUNT; i++){
int userID = (int)SkeletonFrame.SkeletonData[i].dwTrackingID;
char buffer [33];
sprintf(buffer,"%lu",SkeletonFrame.SkeletonData[i].dwTrackingID);
string myID2 = buffer;
cout << "groupID " << groupID << endl;
cout << "myID2 " << myID2 << endl;
if(myID2 == groupID){ countExistance2++;}
}
// user lost
if(countExistance2 == 0){
delete g3D[groupID];
g3D.erase(groupID);
cout << "*************deleted*******" << endl;
}
}
}
Basicly, I am trying to erase the dedicated slot to a skeleton in a map called g3D in every update of the skeleton frame if the skeleton is lost.
Any ideas or sharp eyes are appreciated.
Finally I solved the problem by counting the frames which do not have a tracked skeleton. Skeleton data has 6 slots and in some frames its tracking id is not set to NUI_SKELETON_TRACKED.
Thus, If the number of empty skeleton slots exceeds 20 (which means appx 3-4 successive empty frames), I assume the user is lost.
// handle user exit
// The skeleton is not tracked in every successive frame, so use g3DCounts to count the number of frames
map<string,Group3D*> g3D_copy = g3D;
for(map<string,Group3D*>::iterator mit = g3D_copy.begin();mit != g3D_copy.end();mit++){
if(mit->second->getType() == "KINECT_SKELETON")
{
string groupID = mit->first;
for (int i = 0; i < NUI_SKELETON_COUNT; i++){
char buffer [33];
sprintf(buffer,"%lu",SkeletonFrame.SkeletonData[i].dwTrackingID);
string myID2 = buffer;
if(myID2 == groupID){ g3DCounts[groupID] = 0;}
else{ g3DCounts[groupID] += 1;}
}
if(g3DCounts[groupID] > 20){
delete g3D[groupID];
g3D.erase(groupID);
cout << "*************deleted successfully*******" << endl;
}
}
}
Hope it helps others

How to rewrite token stream more than once using ANTLR4

I implement simple preprocessor using the great ANTLR4 library. The program itself runs in several iterations - in each iteration the future output is modified slightly.
Currently I use TokenStreamRewriter and its methods delete, insertAfter, replace and getText.
Unfortunately I can't manage to rewrite tokens that was rewritten before (got IllegalArgumentException). This is not a bug but according to the source code multiple replacement can't be achieved in any way.
I suppose that a proper solution exists as this appears to be a common problem. Could anyone please hint me? I'd rather use some existing and tested solution than reimplement the rewriter itself.
Maybe the rewriter isn't the right tool to use.
Thanks for help
Good evening
Now a dynamic code for the same problem. First you must have made visible in your listener class the Token stream and the rewriter
Here is the code of the constructor of my VB6Mylistener class
class VB6MYListener : public VB6ParserListener {
public: string FicName;
int numero ; // numero de la regle
wstring BaseFile;
CommonTokenStream* TOK ;
TokenStreamRewriter* Rewriter ;
// Fonctions pour la traduction avec le listener void functions
created by ANTLR4 ( contextes )
VB6MYListener( CommonTokenStream* tok , wstring baseFile, TokenStreamRewriter* rewriter , string Name)
{
TOK = tok; // Flux de tokens
BaseFile = baseFile; // Fichier entree en VB6
Rewriter = rewriter;
FicName = Name; // Nom du fichier courant pour suivi
}
Here in a context i cross with the listener. The Tokenstream is TOK visible by all the functions void
std::string retourchaine;
std::vector<std::string> TAB{};
for (int i = ctx->start->getTokenIndex(); i <= ctx->stop>getTokenIndex(); i++)
{
TAB.push_back(TOK->get(i)->getText()); // HERE TOK
}
for (auto element : TAB)
{
if (element == "=") { element = ":="; }
if (element != "As" && element != "Private" && element != "Public")
{
std::cout << element << std::endl;
retourchaine += element ; // retour de la chaine au contexte
}
}
retourchaine = retourchaine + " ;";
Rewriter->replace(ctx->start, ctx->stop, retourchaine );
`
A workaround I am using because I need to make a replacement in the token and the Tokenrewriter does not make the job correctly when you have multiple replacements in one context.
In each context I can make the stream of tokens visible and I use an array to copy all the tokens in the context and create a string with the replacement and after that, I use Rewriter->replace( ctx->start , ctx->stop , tokentext ) ;
Some code here for a context:
string TAB[265];
string tokentext = "";
for (int i = ctx->start->getTokenIndex(); i <= ctx->stop->getTokenIndex(); i++)
{
TAB[i] = TOK->get(i)->getText();
// if (TOK->get(i)->getText() != "As" && TOK->get(i)->getText() != "Private" && TOK->get(i)->getText() != "Public")
//if (TOK->get(i)->getText() == "=")
//{
if (TAB[i] == "=") { TAB[i] = ":="; }
// if (TAB[i] == "=") { TAB[i] = "="; } // autres changements
if (TAB[i] != "As" && TAB[i] != "Private" && TAB[i] != "Public") { tokentext += TAB[i]; }
cout << "nombre de tokens du contexte" << endl;
cout << i << endl;
}
tokentext = tokentext + " ;";
cout << tokentext << endl;
Rewriter->replace(ctx->start, ctx->stop, tokentext);
It's a a basic code I use to make the job robust. Hope this will be useful.
i think that rewriting the token stream is not a good idea, because you can't
treat the general case of a tree. The TokenStreamRewriter tool of ANTLR is usefulness. If you use a listener , you can't change the AST tree and the contexts created by ANTLR. you must use a Bufferedwriter to do the job for rewriting the context you change locally in the final file of your translation.
Thanks to Ewa Hechsman and her program on github on a transpiler from Pascal to Python.
I think it'a real solution for a professional project.
So i agree with Ira Baxter. we need a rewriting tree

What's the simplest way to execute a query in Visual C++

I'm using Visual C++ 2005 and would like to know the simplest way to connect to a MS SQL Server and execute a query.
I'm looking for something as simple as ADO.NET's SqlCommand class with it's ExecuteNonQuery(), ExecuteScalar() and ExecuteReader().
Sigh offered an answer using CDatabase and ODBC.
Can anybody demonstrate how it would be done using ATL consumer templates for OleDb?
Also what about returning a scalar value from the query?
With MFC use CDatabase and ExecuteSQL if going via a ODBC connection.
CDatabase db(ODBCConnectionString);
db.Open();
db.ExecuteSQL(blah);
db.Close();
You should be able to use OTL for this. It's pretty much:
#define OTL_ODBC_MSSQL_2008 // Compile OTL 4/ODBC, MS SQL 2008
//#define OTL_ODBC // Compile OTL 4/ODBC. Uncomment this when used with MS SQL 7.0/ 2000
#include <otlv4.h> // include the OTL 4.0 header file
#include <stdio>
int main()
{
otl_connect db; // connect object
otl_connect::otl_initialize(); // initialize ODBC environment
try
{
int myint;
db.rlogon("scott/tiger#mssql2008"); // connect to the database
otl_stream select(10, "select someint from test_tab", db);
while (!select.eof())
{
select >> myint;
std::cout<<"myint = " << myint << std::endl;
}
}
catch(otl_exception& p)
{
std::cerr << p.code << std::endl; // print out error code
std::cerr << p.sqlstate << std::endl; // print out error SQLSTATE
std::cerr << p.msg << std::endl; // print out error message
std::cerr << p.stm_text << std::endl; // print out SQL that caused the error
std::cerr << p.var_info << std::endl; // print out the variable that caused the error
}
db.logoff(); // disconnect from the database
return 0;
}
The nice thing about OTL, IMO, is that it's very fast, portable (I've used it on numerous platforms), and connects to a great many different databases.
I used this recently:
#include <ole2.h>
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#include <oledb.h>
void CMyDlg::OnBnClickedButton1()
{
if ( FAILED(::CoInitialize(NULL)) )
return;
_RecordsetPtr pRs = NULL;
//use your connection string here
_bstr_t strCnn(_T("Provider=SQLNCLI;Server=.\\SQLExpress;AttachDBFilename=C:\\Program Files\\Microsoft SQL Server\\MSSQL.1\\MSSQL\\Data\\db\\db.mdf;Database=mydb;Trusted_Connection=Yes;MARS Connection=true"));
_bstr_t a_Select(_T("select * from Table"));
try {
pRs.CreateInstance(__uuidof(Recordset));
pRs->Open(a_Select.AllocSysString(), strCnn.AllocSysString(), adOpenStatic, adLockReadOnly, adCmdText);
//obtain entire restult as comma separated text:
CString text((LPCWSTR)pRs->GetString(adClipString, -1, _T(","), _T(""), _T("NULL")));
//iterate thru recordset:
long count = pRs->GetRecordCount();
COleVariant var;
CString strColumn1;
CString column1(_T("column1_name"));
for(int i = 1; i <= count; i++)
{
var = pRs->GetFields()->GetItem(column1.AllocSysString())->GetValue();
strColumn1 = (LPCTSTR)_bstr_t(var);
}
}
catch(_com_error& e) {
CString err((LPCTSTR)(e.Description()));
MessageBox(err, _T("error"), MB_OK);
_asm nop; //
}
// Clean up objects before exit.
if (pRs)
if (pRs->State == adStateOpen)
pRs->Close();
::CoUninitialize();
}
Try the Microsoft Enterprise Library. A version should be available here for C++. The SQlHelper class impliments the methods you are looking for from the old ADO days. If you can get your hands on version 2 you can even use the same syntax.