My problem is that no method that used to work on string works on wstring.
So I'm asking how I could easily clear wstring for aesthetical purpose.
My code right now:
while (!foundRightOne)
{
wstring cTitle;
ForegroundWindow = GetForegroundWindow();
cout << "FRGW " << ForegroundWindow << endl;
int len = GetWindowTextLengthW(ForegroundWindow) + 1;
wchar_t * windowTitle = new wchar_t[len];
GetWindowTextW(ForegroundWindow, windowTitle, len);
title += windowTitle;
// OUTPUT
cTitle = L"Title: ";
cTitle += title;
wcout << cTitle << endl;
cTitle = ' ';
//OUTPUT
keyPress = getchar();
system("CLS");
if (keyPress == 'y' || keyPress == 'Y')
{
foundRightOne = true;
}
}
Basically it loops while I press y or Y, I press when I see the right cTitle and after ~20 cycles cTitle gets fully filled with text from last cycles.
std::wstring::clear should work, as both it and std::string are std::basic_strings. Check out std::basic_string documentation if you're somehow having trouble.
#include <iostream>
int main()
{
std::string regularString("regular string!");
std::wstring wideString(L"wide string!");
std::cout << regularString << std::endl << "size: " << regularString.size() << std::endl;
std::wcout << wideString << std::endl << "size: " << wideString.size() << std::endl;
regularString.clear();
wideString.clear();
std::cout << regularString << std::endl << "size: " << regularString.size() << std::endl;
std::wcout << wideString << std::endl << "size: " << wideString.size() << std::endl;
}
Output:
regular string!
size: 15
wide string!
size: 12
size: 0
size: 0
Here's an ideone link to that code.
Related
I'm making a test program for starting with C++ :)
It's showing wrong values after first print
This is the code (very simple)
#include "pch.h"
#include <iostream>
#include <Windows.h>
using namespace std;
int main()
{
int varInt = 123456;
char varString[] = "DefaultString";
char arrChar[128] = "Long char array right there ->";
int * ptr2int;
ptr2int = &varInt;
int ** ptr2ptr;
ptr2ptr = &ptr2int;
int *** ptr2ptr2;
ptr2ptr2 = &ptr2ptr;
while(1){
cout << "Process ID: " << GetCurrentProcessId() << endl;
cout << "varInt (0x" << &varInt << ") = " << varInt << endl;
cout << "varString (0x" << &varString << ") = " << varString << endl;
cout << "varChar (0x" << &arrChar << ") = " << arrChar << endl;
cout << "ptr2int (0x" << hex << &ptr2int << ") = " << ptr2int << endl;
cout << "ptr2ptr (0x" << hex << &ptr2ptr << ") = " << ptr2ptr << endl;
cout << "ptr2ptr2 (0x" << hex << &ptr2ptr2 << ") = " << ptr2ptr2 << endl;
cout << "Press ENTER to print again." << endl;
getchar();
cout << "-----------------------------------" << endl;
}
return 0;
}
The expected results are obvious, as the code is published as is:
Process ID is integer so should return 12704 (or any int value) instead of 31a0
varInt it's also integer and should return 123456 instead of 1e240
1e240 is the same thing as 123456 in hex. The first iteration will print 123456 correctly but after you set the base flag of cout to hex mode, you need to set it back to dec to print 123456 again on the next loop.
cout << "varInt (0x" << &varInt << ") = " << dec << varInt << endl;
See here for documentation.
I am a beginner at c++ and I want to create simple game. You have vector of strings, then you check if line input matched the right answer.
I want to generate random number 1 ,2 or 3. Then check if line matches correct answer and count the points.
I am probably missing something basic, yet I dont know what.
Problems:
Input line get correctly read on only first iterations
somehow points (tocke) jumps to 45763 after finishing.
At beginning time (cas) is sometimes 2.
Code:
#include <iostream>
#include <vector>
#include <stdlib.h>
#include <time.h>
#include <string>
int main() {
int runde;
int tocke;
int cas;
std::cout << "\n" << "Pravila igre:" << "\n" << "Za pravilen odgovor dobis 1 tocko, za napacnega zgubis 2!"<<
"\n" << "Stevilo zivljenj si izberes sama!"<< "\n" << "\n" ;
std::cout << "Izberi stevilo zivljenj!:" << "\n";
std::cin >> runde ;
std::vector<std::string> latin = {"carum carvi", "artemisia absiinthium","coriandrum sativum"};
std::vector<std::string> slovene = {"navadna kumina", "pravi pelin", "koriander"};
tocke << 0;
cas << 0;
do {
int ind;
cas << cas + 1;
std::cout << "Round " << cas <<"! Ladies and gentlemans, buckle your seatbelts!"<<"\n" << "\n" ;
ind = std::rand() % 3;
std::cout << "ime rastline: " << slovene[ind] << "\n";
std::cin.ignore();
std::string line;
getline(std::cin, line);
std::cout << "\n";
if (latin[ind] == line){
std::cout << "Pravlino! Tocka zate!" << "\n";
tocke << tocke + 1;
std::cout << "Tocke == " << tocke << "\n" << "Zivjenja == " << runde << "\n" << "Prezivete runde == " << cas << "\n"<< "\n";
}
else
{
std::cout << "Napaka! :D" << "\n";
std::cout << "Pravilen odgovor == " << latin[ind] << "\n";
-- runde ;
tocke << tocke - 2;
std::cout << "Tocke == " << tocke << "\n" << "Zivjenja == " << runde << "\n" << "Prezivete runde == " << cas << "\n"<< "\n";
}
}while(runde >= 0 );
std::cout << "\n"<<"Stevilo tock == " << tocke <<"\n" << "St. prezivetih rund == " << cas - 1
<< "\n" ;
}
You seem to have a misconception regarding operators. << is NOT assignment, use = instead. So tocke << 0; doesn't assign 0 to tocke, it does bitshifting (on an uninitialized variable), then discards the result. tocke stays uninitialized and this causes problems later.
Instead of this:
tocke << 0;
cas << 0;
Do this:
tocke = 0;
cas = 0;
Also instead of cas << cas + 1; do cas++ and instead of tocke << tocke - 2; do tocke -= 2;. To learn how the assignment operators work, you can read about them here. Last but not least, try to see if your compiler gives you any warnings, it should complain about using uninitialized values.
First, I'm sorry but I don't speak english very well.
My problem is that I want my stream go back begining of the file. So, i apply the clear() method upon my stream object, but after this, getline() always return 0 (false).
I don't find the solution. Somebody has an idea about this problem?
So, this is my code:
void Tools::tokenizeAll(string filename, string separator){
char str[LINESIZE] = {0};
int lineNumber = 0, j = 0;
ifstream stream;
stream.open(filename.c_str(), std::ifstream::in);
if(stream){
while(stream.getline(str, LINESIZE)){
lineNumber++;
}
//allocation dynamique du tableau à deux dimensions
string** elementsTable = NULL;
elementsTable = new string*[lineNumber];
for( int i = 0 ; i < lineNumber ; i++ ) elementsTable[i] = new string[4];
std::cout << " good()=" << stream.good() << endl;
std::cout << " eof()=" << stream.eof() << endl;
std::cout << " fail()=" << stream.fail() << endl;
std::cout << " bad()=" << stream.bad() << endl;
cout << endl;
stream.clear();
std::cout << " good()=" << stream.good() << endl;
std::cout << " eof()=" << stream.eof() << endl;
std::cout << " fail()=" << stream.fail() << endl;
std::cout << " bad()=" << stream.bad() << endl;
cout << endl;
cout << stream.getline(str, LINESIZE) << endl;//return 0
}
else cout << "ERREUR: Impossible d'ouvrir le fichier en lecture." << endl;
}
Thank you very much (and thank you to warn me about my english errors ;) )
Calling clear() only resets the error flags. To "rewind" the stream to the beginning, you'll also need to use seekg:
stream.seekg(0, std::ios::beg)
Note that this operation can fail, too, so you might want to check for errors.
I tried to format output strings in my console application (like a table)
cout << "\n\n-----------------\n";
cout << setw(8) << left << "F\t|";
cout << setw(8) << left << "x\t|";
cout << "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "\t|";
cout.width(8);
cout.setf(ios::left);
cout << x << "\t|";
cout << "\n-----------------\n\n";
But as result my output looks like this
What's wrong with my upper string formatting?
I used the same code as you did and got the same output until I removed the \t at the end of the line. See the new code:
cout << "\n\n-----------------\n";
cout << setw(8) << left << "F\t|";
cout << setw(8) << left << "x\t|";
cout << "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "|";
cout.width(8);
cout.setf(ios::left);
cout << x << "|";
cout << "\n-----------------\n\n";
As already noted, it's the tabs that are causing the problem.
I would not stop at just removing the tabs though. As it stands right now, your code is highly repetitive and next to impossible to maintain. I'd do a (nearly) complete rewrite, with a couple of functions to cut down on the repetition. My first cut would probably look something like this:
// format a value in a field of specified width, followed by a separator
template <class T>
string field(T val, int w, char sep = '|') {
stringstream b;
b << setw(w) << left << fixed << setprecision(3) << val << sep;
return b.str();
}
// generate a separator for a specified number of fields,
// each of a specified width
string sep(int c, int w, char val = '-') {
string s(c * (w + 1), val);
return string("\n") + s + "\n";
}
int main() {
static const int w = 8;
double F = 1.234, x = 3.45;
string s = sep(2, w);
cout << "\n" << s;
cout << field("F", w) << field("x", w) << s;
cout << field(F, w) << field(x, w) << s;
}
Seems to me that this makes the code rather more readable and quite a bit more maintainable. For example, if we decided to display an a and b on the next line, it would seem fairly obvious to add something like:
cout << field(a, w) << field(b, w) << s;
...and we wouldn't have to look very hard to be pretty sure it was going to match up with the previous line. Likewise, if we wanted to change a column width, etc.
You may try:
cout << "\n\n-----------------\n";
cout << setw(8) << left << "F\t\t|"; // insert more tab here
cout << setw(8) << left << "x\t|";
cout << "\n-----------------\n";
//...
cout.width(8);
cout.setf(ios::left);
cout << fixed << setprecision(3) << F << "\t|";
cout.width(8);
cout.setf(ios::left);
cout << x << "\t|";
cout << "\n-----------------\n\n";
The console screen looks suspiciously Windows like.
If you are using Windows, you can use the Win32 API to format output more precisely.
In particular, you can use SetConsoleCursorPosition.
COORD position = {x,y};
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(hOut, position);
std::cout<<"This will be printed starting at position x, y"<<std::endl;
Try this:
#include <iostream>
#include <iomanip>
#include <map>
#include <string>
using namespace std;
int main()
{
map< float, float > table =
{
{ 8232.0f, 89.0f },
{ 8232.1f, 89.0f },
{ 8232.2f, 89.0f },
{ 8232.3f, 89.0f },
{ 8232.4f, 89.0f },
{ 8232.5f, 89.0f },
{ 8232.6f, 89.0f },
{ 8232.7f, 89.0f },
{ 8232.8f, 89.0f },
};
const size_t CELL_WIDTH = 25;
const string CELL_LINE( CELL_WIDTH, '=' );
// print the header of table
cout << '|' << CELL_LINE << '|' << CELL_LINE << '|' << endl
<< '|'
<< left << setw( CELL_WIDTH ) << "F" << '|'
<< setw( CELL_WIDTH ) << "R" << "|\n|"
<< CELL_LINE << '|' << CELL_LINE << '|' << endl;
// print the body
// change cout precision
cout << fixed << setprecision( 3 );
for ( auto it : table )
cout << "| " << setw( CELL_WIDTH - 1 ) << it.first
<< "| " << setw( CELL_WIDTH - 1 ) << it.second
<< "|\n";
// print the footer
cout << '|' << CELL_LINE << '|' << CELL_LINE << '|' << endl;
return 0;
}
this is the result:
I want to convert the strFileNotifyInfo[1].FileName(Wchar_t) to a string so that i can see the filepath. but i can't make it work.
Here is my code:
while(TRUE)
{
if( ReadDirectoryChangesW( hDir, (LPVOID)&strFileNotifyInfo, sizeof(strFileNotifyInfo), FALSE, FILE_NOTIFY_CHANGE_LAST_WRITE || FILE_NOTIFY_CHANGE_CREATION, &dwBytesReturned, NULL, NULL) == 0)
{
cout << "Reading Directory Change" << endl;
}
else
{
cout << ("File Modified: ") << strFileNotifyInfo[1].FileName << endl;
cout << ("Loop: ") << nCounter++ << endl;
}
}
Use wcout when working with wide character data.
std::wcout << L"File Modified: " << strFileNotifyInfo[1].FileName << std::endl;
You should also keep in mind that FileName is not null-terminated.
WCHAR* filename_w = strFileNotifyInfo[1].FileName;
DWORD filename_len = strFileNotifyInfo[1].FileNameLength;
std::string filename(filename_w, filename_w + filename_len);
std::cout << "File Modified: " << filename << std::endl;