Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 7 years ago.
Improve this question
I'm studying the string type, and I stumbled across char string[]. Its confusing and I don't even know what it is. Its strange that i can't declare a string after I use it, because its using like a variable and it doesn't allow me to declare other strings. So how to add a name to that char array? Here is the code so I hope its understandable what I mean. Thanks.
#include "iostream"
#include "string.h"
using namespace std;
int main(){
char string[] = "hello stackoverflow";
string word("hello stackoverflow"); //cant declare "word"
//because i declare it above, and i want to know how to avoid that..
cout<<word;
cout<<string;
}
the code I'm studying is this:
/* Trim fat from windows*/
#define WIN32_LEAN_AND_MEAN
#pragma comment(linker, "/subsystem:windows")
/* Pre-processor directives*/
#include <windows.h>
#include "string.h"
/* Windows Procedure Event Handler*/
LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT paintStruct;
/* Device Context*/
HDC hDC;
/* Text for display*/
char string [] = "hi im a form"; //this is whats i don't understand what //it is
/* Switch message, condition that is met will execute*/
switch(message)
{
/* Window is being created*/
case WM_CREATE:
return 0;
break;
/* Window is closing*/
case WM_CLOSE:
PostQuitMessage('0');
return 0;
break;
/* Window needs update*/
case WM_PAINT:
hDC = BeginPaint(hwnd,&paintStruct);
/* Set txt color to blue*/
SetTextColor(hDC, COLORREF(0xffff1a));
/* Display text in middle of window*/
TextOut(hDC,150,150,string,sizeof(string)-1); //and here why its //only able to declare it as "string" and not as a name
EndPaint(hwnd, &paintStruct);
return 0;
break;
default:
break;
}
return (DefWindowProc(hwnd,message,wParam,lParam));
}
char c_str[] = "hello";
This declares a variable named c_str of type char [6] a.k.a static array of 6 chars initialized with "hello";
std::string cpp_string("hello");
This declares a variable named cpp_string of type std::string initialized with "hello". If you add using namespace std;, then you can use string instead of std::string.
All declarations of a variable must have the same type. You cannot define a variable multiple times.
You should not declare a variable with the same name as a type.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 months ago.
Improve this question
I'm trying to look into smart card reading and I've immediately encountered an issue that I'm struggling with. I've called the SCardEstablishContext and I'm now trying to list the cards readers. I'm getting success and Its telling me there are 89 bytes worth of string data but the string isn't being written out to me. I'm not sure what the issue could be, my code is pretty much identical to the example code on msdn only I've gotten some memory using virtualalloc for the string to.
I've tried changing types and connecting, disconnecting smart card reader, restarting the system etc etc stepping through in the debugger for each and every change attempted. Same issue, either in getting 89 empty bytes or im hitting my asserts for not succeeding at getting the context or so on.
#include <Windows.h>
#include <stdint.h>
#include <winscard.h>
#include <stdio.h>
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;
typedef uint64_t u64;
typedef uint32_t b32;
typedef int8_t i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
#define l_persist static
#define gvar static
#define internal static
#define KiloBytes(Value) ((Value) * 1024LL)
#define MegaBytes(Value) (KiloBytes(Value) * 1024LL)
#if INTERNAL
#define Assert(exp) if (!(exp)) {*((u8*)0) = 0;}
#define AssertWithMessage(exp, message) if (!(exp)) {OutputDebugString("\nAssertion failed: "); OutputDebugString(message); OutputDebugString("\n"); Assert(exp);}
#else
#define Assert(exp)
#define AssertWithMessage(exp, message)
#endif
#define U32_MAX 0xFFFFFFFF
b32 G_IsRunning = true;
LRESULT CALLBACK MainWindowCallback(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam)
{
LRESULT Result = 0;
switch(Message)
{
case WM_CLOSE:
case WM_QUIT:
case WM_DESTROY:
{
G_IsRunning = false;
} break;
default:
{
Result = DefWindowProc(Window, Message, WParam, LParam);
}
}
return Result;
}
void MessagePump(HWND Window)
{
MSG Message = {};
u32 InputCount = 0;
while(PeekMessage(&Message, Window, 0, 0, PM_REMOVE))
{
switch(Message.message)
{
case WM_QUIT:
{
G_IsRunning = false;
} break;
default:
{
TranslateMessage(&Message);
DispatchMessage(&Message);
} break;
}
}
}
INT CALLBACK
WinMain(HINSTANCE Instance, HINSTANCE PrevInstance, LPSTR CommandLine, INT ShowCommand)
{
WNDCLASS WindowClass = {};
WindowClass.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW;
WindowClass.lpfnWndProc = MainWindowCallback;
WindowClass.hInstance = Instance;
WindowClass.lpszClassName = "MainWindowClass";
if (RegisterClass(&WindowClass))
{
HWND Window = CreateWindowEx(0,WindowClass.lpszClassName, "Main Window", WS_OVERLAPPEDWINDOW|WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,0,0,Instance, 0);
if (Window)
{
SCARDCONTEXT CardContext = U32_MAX;
LONG CardContextSuccess = SCardEstablishContext(SCARD_SCOPE_USER, 0, 0, &CardContext);
Assert(CardContextSuccess == SCARD_S_SUCCESS);
u8 *Memory = (u8*)VirtualAlloc(0, KiloBytes(1), MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
u8 *MemoryHead = Memory;
LPSTR ReadersList = (char*)MemoryHead;
LPSTR ReadersListWip = 0;
DWORD ReadersListSize = 0;
LONG CardReadersListStatus = SCardListReadersA(CardContext, 0, (LPSTR)&ReadersList, &ReadersListSize);
Assert(ReadersList);
Assert(ReadersListSize);
switch(CardReadersListStatus)
{
case SCARD_S_SUCCESS:
{
ReadersListWip = ReadersList;
while ( '\0' != *ReadersListWip )
{
printf("Reader: %S\n", (wchar_t*)ReadersListWip );
// Advance to the next value.
ReadersListWip = ReadersListWip + wcslen((wchar_t *)ReadersListWip) + 1;
}
} break;
case SCARD_E_NO_READERS_AVAILABLE:
{
AssertWithMessage(CardReadersListStatus == SCARD_S_SUCCESS, "There were no card readers available");
G_IsRunning = false;
} break;
case SCARD_E_READER_UNAVAILABLE:
{
AssertWithMessage(CardReadersListStatus == SCARD_S_SUCCESS, "The card reader was unavailable");
G_IsRunning = false;
} break;
default:
{
AssertWithMessage(CardReadersListStatus == SCARD_S_SUCCESS, "Some other issue with card reader listing");
G_IsRunning = false;
}
}
while(G_IsRunning)
{
MessagePump(Window);
LPSCARDHANDLE CardHandle = 0;
DWORD ActiveProtocol = 0;
LONG CardConnectStatus = SCardConnectA(CardContext, ReadersList, SCARD_SHARE_SHARED, SCARD_PROTOCOL_T0, (LPSCARDHANDLE)&CardHandle, &ActiveProtocol);
Assert(CardConnectStatus == SCARD_S_SUCCESS);
}
}
}
return 0;
}
Above is the code as it stands after my last batch of tests. I am quite rusty but I can't see why I'm getting a size back but not getting the strings.
Is there an alternative api for card reading?
I recognize that the loop is no good at the end there that was an artefact left from some previous efforts earlier on. I'm stepping through it anyway so I'm ignoring it for now.
Thanks to Raymond Chen's comments I've realised my errors and can progress in learning the SCARD api. Mostly my mistake, but I feel that the documentation on MSDN could have been clearer. Particularly in regards to the third argument to SCardListReaders() which is an in/out parameter. I did not realise that setting the parameter to zero would return the size and then would require a second call to the same function with the buffer of sufficient length. I failed to notice the SCARD_AUTOALLOCATE section of the documentation. Not entirely sure how I manage to overlook that but I somehow did. I found this function quite confusing for those reasons.
Credit for helping me realise my errors goes to the infamous Raymond Chen.
Below I've written some annotated demonstration code for anyone in future who might find the api confusing as I found earlier this evening.
LPSTR ReadersList; //im no longer initializing to zero here because a null argument tells the function to just return the size of the string(s).
#define one_call_version 0
#if one_call_version
DWORD ReadersListSize = SCARD_AUTOALLOCATE; //passing this will cause the function to allocate some memory for you and return the strings inside that block of memory.
LONG CardReadersListStatus = SCardListReadersA(CardContext, 0, (LPSTR)&ReadersList, &ReadersListSize);
//ReadersListSize now points to a populate block of memory that needs to be frees via SCardFreeMemory or process termination.
#else //ReadersList = (LPSTR)calloc(ReadersListSize, sizeof(char)); //ReadersList = (LPSTR)malloc(ReadersListSize);
DWORD ReadersListSize = 0;
LONG CardReadersListStatus = SCardListReadersA(CardContext, 0, 0, &ReadersListSize); //1ST// call with null 3rd argument will just get the size of the readers list string
//ReadersListSize should now be modified to contain the minimum required size of memory allocation to contain the string(s) in bytes.
ReadersList = (LPSTR)VirtualAlloc(0, ReadersListSize, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
CardReadersListStatus = SCardListReaders(CardContext, 0, ReadersList, &ReadersListSize); //2ND// call with the buffer of sufficient size for the string(s) as 3rd argument should populate the buffer
#endif //Should now have the ReadersList populated with the names of the connected smart card reader devices.
I'm writing some example programs for a programming class using WinAPI. I'm familiar with GUI programming, but not in C++. As part of a test I ran into an anomaly. I'm hoping someone will know what I'm doing wrong and be able to explain the fix. Below is the callback function. Most of the code was copied directly from an example on basic paint.
LRESULT CALLBACK WinProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l)
{
PAINTSTRUCT ps;
HDC hdc;
std::string txt = "Hello\0";
switch(msg)
{
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc, 0, 60, txt.c_str(), 45);
EndPain, h, &ps);
}
}
So, the function is supposed to simply print "Hello" on the GUI, but instead I was seeting "Hello xc". I expanded the length of the string to 45 and saw a lot more. It prints random bits of text. I've seen class names and string values which were going to cout.
I have no idea why this is happening, but it appears that txt is being read far past the end of the buffer. I added a \0. No difference. The value is different every time.
Any idea what is going on?
TextOut uses the final parameter cchString to determine how many characters to print. You must tell it the correct number.
https://msdn.microsoft.com/en-us/library/windows/desktop/dd145133.aspx
lpString [in]
A pointer to the string to be drawn. The string does not need to be zero-terminated, because cchString specifies the length of the string.
cchString [in]
The length of the string pointed to by lpString, in characters.
TextOut() does not stop writing text at the null terminator, it will just keep going for as long as you specified. The last parameter tells the function how many characters to write. Instead of giving it 45, give it something like strlen(txt.c_str()).
I'm having issues trying to store wchar_t character arrays in a global array,
below is the code for what i want to do: -
wchar_t **WinList //Global array store
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)
{
int NumMembers;
if (WinList == nullptr)
{
NumMembers = 0;
}
else
{
NumMembers = (sizeof(**WinList) / sizeof(wchar_t));
}
wchar_t class_name[300];
GetClassName(hwnd, class_name, 300);
WinList = new wchar_t * [NumMembers + 1];
WinList[NumMembers] = class_name;
return TRUE;
}
The error:
Unhandled exception at 0x765CE2C3 (usp10.dll) in Win32Project4.exe: 0xC0000005: Access violation reading location 0xCDCDCDCD." is occuring below at the TextOut function, WinList = 0x002802a0 {0xcdcdcdcd <Error reading characters of string.>} : -
case WM_PAINT:
if (WinList != nullptr)
{
PAINTSTRUCT ps;
HDC hDC = BeginPaint(hwnd, &ps);
for (int iLoop = 0; iLoop != sizeof(WinList); iLoop++)
{
TextOut(hDC, 5, iLoop*10, WinList[iLoop], (sizeof(WinList[iLoop]) / sizeof(wchar_t)));
}
}
break;
I have tried various variations of functions and code using things like malloc and mcscpy. I seem to however be misunderstand the scope of the pointer I think. I do not seem to be able to get my head around it. Any explanation would be much appreciated. I'm using VS 2013, and this is more of a learning concept rather than is there a better way. However I would also appreciate the 'better way' solution.
Regards,
HonkeyPig
Your main problem is that you store result of the call-back function in local variable that is immediately discarded on return..
Besides that
(sizeof(**WinList) / sizeof(wchar_t))
is exactly sizeof(pointer)/2 that is 2 on a 32 bit architecture....
So i am making a basic tic tac toe game as my first program in win32 (just for fun to learn more, no school assignment or anything). I have most of the UI done and the basic gameplay such as clicking squares and placing x's or o's appropriately. I have written it so that it recognizes who is the winner when the game is over and can display a little text window saying "PLAYER 1 WINS!" etc....
No my question is concerning how to display the score. My idea is to have a int variable called scoreplayer1, and when the player wins, i will increase it by 1 (scoreplayer1++). I then want to have the window that has the previous score change to the new score. This is what i have so far (I am going to take out all of the code that is not relevant to this question but if you need more let me know):
My Global Variables:
//Global Variables
HINSTANCE hInst; // current instance
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name
HWND hwnd1, hwnd2, hwnd3, hwnd4, hwnd5, hwnd6, hwnd7, hwnd8;
HWND hwnd9, hwndscore1, hwndscore2, hWnd;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass(HINSTANCE hInstance);
BOOL InitInstance(HINSTANCE, int);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK About(HWND, UINT, WPARAM, LPARAM);
int determinewinner();
int showscore(int win_value);
int scoreplayer1,scoreplayer2;
The CreateWindow function that originally creates the score windows (they start out blank):
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
case WM_CREATE:
hwndscore1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("STATIC"),TEXT(""), WS_CHILD|WS_VISIBLE|SS_CENTER, 20,285,100,20,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
hwndscore2 = CreateWindowEx(WS_EX_CLIENTEDGE,TEXT("STATIC"),TEXT(""), WS_CHILD|WS_VISIBLE|SS_CENTER, 130,285,100,20,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
Then the function that is trying to handle changing the score window:
int showscore(int win_value)
{
if(win_value==1)
{ scoreplayer1++;
DestroyWindow(hwndscore1);
hwndscore1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("STATIC"),TEXT(scoreplayer1), WS_CHILD|WS_VISIBLE|SS_CENTER, 20,285,100,20,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
return (scoreplayer1);} // This return part is just temporary because it wants
// the function to return a value, it doesn't come into play
}
The idea was to destroy the old window and simply recreate a new window with the new score (that seemed to be the easiest way to go about doing it). I know where the problem is, it says i can't put the int scoreplayer1 variable in that TEXT("scoreplayer1") part in the last CreateWindowEx function. The error is: argument of typ int is incompatible with parameter of type LPCSTR.
So how can change the creation of that last window so that it will display a int variable (such as scoreplayer1) that will be increasing as the game goes on? Thanks!
*EDIT***
In response to a comment i attempted to use itoa() to fix the problem, i did the following:
int showscore(int win_value)
{ if(win_value==1)
{ scoreplayer1++;
char score1[1];
itoa(scoreplayer1, score1, 1);
DestroyWindow(hwndscore1);
hwndscore1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("STATIC"),TEXT(score1), WS_CHILD|WS_VISIBLE|SS_CENTER, 20,285,100,20,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
return (scoreplayer1);}
Which forces the program to break as soon as i get to that point in the game... Any ideas on what i did wrong?
Converting an integer to a string can be made MANY different ways in C and C++.
Your edited code fails because the string is 1 character long, and ALL numbers are guaranteed to NOT fit in one character, since all numbers take one character for the string itself, and a further character for the zero byte marking the end of the string. If the number is greater than 9, it will take up three characters, greater than 99 will take 4, and so on.
In C++, I would suggest that, although a bit longer, usign a stringstream to output the number to is an easier/safer method that avoids the problems if figuring out how much space you need for the string (and allows output of more complex things than just one integer, since you can simply combine any output, just like you would for console output using cout).
Something like this:
std::stringstream ss;
ss << scoreplayer1;
hwndscore1 = CreateWindowEx(WS_EX_CLIENTEDGE, TEXT("STATIC"),ss.str().c_str(), WS_CHILD|WS_VISIBLE|SS_CENTER, 20,285,100,20,hWnd,HMENU(NULL),GetModuleHandle(NULL),NULL);
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 5 years ago.
I am kind of stuck on this and would appreciate help in solving this please. I am using window GDI, and according to this link, including windows.h is what is needed to work with the TextOut function, among others, but I am still getting some undefined reference error messages and I am stuck.
**undefined reference to `TextOutA#20'|
undefined reference to `CreateDCA#16'|
undefined reference to `Escape#20'|
undefined reference to `DeleteDC#4'|**
#include <Windows.h>// HDC is a typedef defined in the windows.h library
#include <stdlib.h>
#include <stdio.h>
#include <fstream>
#include <strstream>
#include <string.h>
using namespace std;
#define IDM_QUIT 102
#define EXAMPLE 101
#define IDM_PRINT 27
#define IDM_SHOW 1
//this excerpt demonstrates how to get the handle to a device context ysing the BegingPaint() GDI function
long FAR PASCAL _export WINDOWPROCEDURE(HWND hwnd, UINT message, UINT wParam, LONG Param)
{
HDC hdc;
PAINTSTRUCT ps;
RECT area;
char PInfo[80]="";
char DriverName[20];
char DeviceName[40];
char Other[20];
int X,Y;
X=100;
Y=100;
switch(message)
{
case WM_PAINT:
hdc = BeginPaint(hwnd, &ps);
TextOut(hdc,X,Y, "Speed of Light", 14);
EndPaint(hwnd, &ps);
case IDM_SHOW:
hdc = GetDC(hwnd);
TextOut(hdc, X,Y, "Speed of Light", 14);
ReleaseDC(hwnd, hdc);
case IDM_PRINT:
GetProfileString("windows", "device", "", PInfo,80);
istrstream In(PInfo);
In.getline(DeviceName, 80, ',');
In.getline(DriverName, 80, ',');
In.getline(Other,80, ',');
hdc = CreateDC(DriverName, DeviceName, Other, NULL);
Escape(hdc,
STARTDOC,8,
(LPSTR)"EXAMPLE",0L);
TextOut(hdc, X, Y, "Speed of Light", 14);
Escape(hdc, NEWFRAME, 0,0L, 0L);
Escape(hdc, ENDDOC, 0,0L, 0L);
DeleteDC(hdc);
}
return 0;
}
Linking to gdi32.lib should solve the problem. :)
Ohh friend,if you have faced this type of error in dev cpp,then go to tool->compliler option->
click on the settings tab ->linker->change dont create console window to "YES"->CLICK OK.Your problem may be solved.