operator< for user defined key of map - C2679 - visual-c++

I'm trying to create a map like
std::map<std::map <std::string,std::string>, MyDataTyp*>,
therefore I put
std::map<std::string, std::string>
in a separate class like:
class TagList {
public:
std::map<std::string, std::string> _map;
TagList() {}
~TagList() {}
void addTag(const std::string tag, const std::string value) { if (tag != "") _map[tag] = value; }
std::string getValue(const std::string tag) {
std::map<std::string, std::string>::iterator it = _map.find(tag);
if (it == _map.end()) return ("");
else return (it->second);
}
};
inline bool operator< (const TagList &a, const TagList &b) {
std::map<std::string, std::string>::iterator it ;
for (it = a._map.begin(); it != a._map.end(); it++) {
std::string myVal1 = it->second;
std::string myVal2 = b._map.find(it->first);
if (myVal2 == "") return false;
if (strcmp(myVal1.c_str(),myVal2.c_str()) > 0) return true;
}
return false;
}
Hope someone can explain me the error message
Error 4 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::_Tree_const_iterator<_Mytree>' (or there is no acceptable conversion) (...)
...and what is the reason for my confision....

Sorry, my fault...
found the answer by myself:
inline bool operator< (const TagList &a, const TagList &b) {
std::map<std::string, std::string>::const_iterator it ;
std::map<std::string, std::string>::const_iterator it2 ;
for (it = a._map.begin(); it != a._map.end(); it++) {
std::string myVal1 = it->second;
it2 = b._map.find(it->first);
std::string myVal2 = it2->second;
if (myVal2 == "") return false;
if (strcmp(myVal1.c_str(),myVal2.c_str()) > 0) return true;
}
return false;
}
it wasn't const
Thx
George

Related

How do i print the char value from file c program?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define BUFFER_SIZE 128
const char *FILE_GAME_DATA_PATH = "./game.txt";
struct game_tag
{
char gname[20];
struct game_tag *next;
} * head;
//struct game_tag g;
typedef struct game_tag GAME;
//file functions
void read_file();
//util functions.
int menu();
void print_game(GAME *game);
void release(GAME *data);
//core
void display_game();
void quite();
//link
int count_elements(GAME *elements);
int count();
int main(void)
{
int selected;
read_file();
while (1)
{
selected = menu();
switch (selected)
{
case 1:
display_game();
break;
default:
printf("cannot find your option!");
break;
}
}
}
void display_game()
{
read_file();
GAME *game = head;
if(game == NULL)
{
printf("\nNo Game!\n");
return;
}
print_game(game);
}
void print_game(GAME *game)
{
int records_count = 0;
printf("\n========== GAME ==========\n");
while(game != NULL)
{
printf("\n");
printf("Game Name: %s\n ", game->gname);
game = game->next;
records_count++;
}
printf("\nRecords: %d has been loaded successfully!\n", records_count);
release(game);
}
int menu()
{
printf("\n(1) Display Game details\n");
int choosen;
printf("\nEnter your option: ");
scanf("%d", &choosen);
return choosen;
}
void add_game(char game_name[20])
{
GAME *temp, *iterator;
temp = (struct game_tag *)malloc(sizeof(struct game_tag));
GAME info;
memcpy(info.gname, game_name, 20);
//temp = head;
iterator = head;
if (head == NULL)
{
head = temp;
head->next = NULL;
}
else
{
while (iterator->next != NULL)
{
iterator = iterator->next;
}
temp->next = NULL;
iterator->next = temp;
}
}
void read_file()
{
if(head != NULL)
{
GAME *temp;
while(head != NULL)
{
temp = head;
head = head->next;
free(temp);
}
}
FILE *file;
file = fopen(FILE_GAME_DATA_PATH, "r");
if(file == NULL)
{
printf("Cannot read file: %s", FILE_GAME_DATA_PATH);
exit(EXIT_FAILURE);
}
char game_name[20];
int i;
while(!feof(file))
{
char no[BUFFER_SIZE];
fgets(game_name, sizeof(game_name), file);
i=0;
while(game_name[i] != '\0')
{
i++;
}
game_name[i] = '\0';
add_game(game_name);
}
fclose(file);
}
void quite()
{
printf("\nGoodbye!");
exit(EXIT_SUCCESS);
}
void release(GAME *data)
{
if (data == NULL)
{
return;
}
// free the nodes
// because it can be use in memory
// we need to clear it first
// before we re-initailize the new data
GAME *temp;
while (data != NULL)
{
temp = data;
data = data->next;
free(temp);
}
}
(1) At this point, I have created the main function
(2) I'm trying to print the value from txt file which is char value that less than 20byte
(3) My error is it read the file properly, but it returns the garbage value
!Error I'm concern that my read_file function doesn't read txt proper or there an error in my condition statement

Wrong result while using _addcarry_u64 on MSVC 2017

I am trying to write a simple library to work with long integers. Using of special optimization based on intrinsic method _addcarry_u64 of 64-bit compiler get an unexpected result in the following code if used optimization. Debug version working as expected.
inline uint64_t addc(const uint64_t& value1, const uint64_t& value2, uint64_t& carry) noexcept
{
uint64_t result;
carry = _addcarry_u64(static_cast<uint8_t>(carry), value1, value2, &result);
return result;
}
template<typename native_t = uintmax_t>
class long_t
{
public:
static_assert(std::is_unsigned_v<native_t>, "unsigned long integer native type must be unsigned");
using native_array_t = std::array<native_t, 2>;
long_t() noexcept;
constexpr long_t(const long_t& that) noexcept = default;
constexpr long_t(long_t&& that) noexcept = default;
constexpr long_t(native_array_t digits) noexcept;
constexpr long_t(const native_t& value) noexcept;
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int> = 0>
constexpr long_t(type_t value) noexcept;
template<typename type_t, std::enable_if_t<std::is_signed_v<type_t>, int> = 0>
constexpr long_t(type_t value) noexcept;
constexpr bool operator==(const long_t& that) const noexcept;
constexpr long_t& operator+=(const long_t& that) noexcept;
constexpr long_t operator+(const long_t& that) const noexcept;
native_array_t digits;
};
template<typename native_t>
inline long_t<native_t>::long_t() noexcept
{
}
template<typename native_t>
inline constexpr long_t<native_t>::long_t(native_array_t digits) noexcept
: digits(digits)
{
}
template<typename native_t>
inline constexpr long_t<native_t>::long_t(const native_t& value) noexcept
: long_t({ value, 0})
{
}
template<typename native_t>
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int>>
inline constexpr long_t<native_t>::long_t(type_t value) noexcept
: long_t({ native_t(value), 0 })
{
}
template<typename native_t>
template<typename type_t, std::enable_if_t<std::is_signed_v<type_t>, int>>
inline constexpr long_t<native_t>::long_t(type_t value) noexcept
: long_t({ static_cast<native_t>(value), (value >= 0 ? 0 : native_t(~0)) })
{
}
template<typename native_t>
inline constexpr bool long_t<native_t>::operator==(const long_t& that) const noexcept
{
if (digits[1] != that.digits[1])
return false;
if (digits[0] != that.digits[0])
return false;
return true;
}
template<typename native_t>
inline constexpr long_t<native_t>& long_t<native_t>::operator+=(const long_t& that) noexcept
{
native_t carry = 0;
digits[0] = addc(digits[0], that.digits[0], carry);
digits[1] = addc(digits[1], that.digits[1], carry);
return *this;
}
template<typename native_t>
inline constexpr long_t<native_t> long_t<native_t>::operator+(const long_t& that) const noexcept
{
return long_t(*this) += that;
}
int main()
{
const bool result = long_t<uintmax_t>(0) + -1 == -1;
std::cout << "result:" << result;
return 0;
}
Output is:
result:0
Replacing of optimized addc version caused to predictable result:
template<typename type_t, std::enable_if_t<std::is_unsigned_v<type_t>, int>>
inline constexpr type_t addc(const type_t& value1, const type_t& value2, type_t& carry) noexcept
{
const type_t tmp = value2 + carry;
const type_t result = value1 + tmp;
carry = (tmp < value2) || (result < value1);
return result;
}
Output is:
result:1
The problem appears on Microsoft Visual Studio 2017 version 15.9.23 on 64-bit C++ compiler in full optimization mode.

How to pass the pointer of a memory buffer created by calloc to a sub function?

Here is my code:
I have to dynamically create some memory for the string Str1 and pass its pointer to the other two functions in a recursive manner. The code compiles but when it enters Function2 it generates an exception saying that cannot write c[i], bad pointer? (i.e. it does not write to Str1)
What am i doing wrong?
void Function1(void)
{
char *Str1;
Str1 = calloc(25, sizeof(char));
pFileIn = fopen("in.txt", "r");
pFileOut = fopen("out.txt", "w+");
if (pFileIn==NULL) printf("Error opening file");
else
{
while (Function2(pFileIn, Str1))
{
if (! Function3(pFileOut, Str1))
{
fseek(pFileOut, 0, SEEK_END);
fprintf(pFileOut, "%s", Str1);
rewind(pFileOut);
}
}
fclose(pFileIn);
fclose(pFileOut);
}
int Function2(FILE* f, char * c)
{
int i=0;
do
{
c[i] = fgetc(f);
if (c[i]==EOF)
return FALSE;
} while (c[i++]!='\n');
c[i] = '\0';
return TRUE;
}
int Function3(FILE* f, char * c)
{
char *Str2;
Str2 = calloc(25, sizeof(char));
while (Function2(f, Str2))
{
if (strcmp(c, Str2)==0)
return TRUE;
}
rewind(f);
return FALSE;
}

How to compare string variable to constant string in visual c++?

I have this piece of code:
#include "stdafx.h"
#include "afx.h"
...
char * connectionType;
...
int readParameters() {
...
//hFile is a file handler previously initialized
result = readParameter(hFile, connectionType);
if (strcmp(connectionType, "3") == 0) {
//do something
} else {
//do other thing
}
...
}
int readParameter(HANDLE hFile, OUT char * buffer) {
BOOL bResult = true;
BOOL continueLine = true;
char inBuffer[1];
DWORD bytesToRead = 1;
DWORD bytesRead = 0;
OVERLAPPED stOverlapped = {0};
char parameter[256] = {};
int counter = 0;
while (continueLine) {
bResult = ReadFile(hFile, inBuffer, sizeof(char), &bytesRead, &stOverlapped);
if (!bResult) {
return 0;
} else if (inBuffer[0] == '\n' || bytesRead == 0) {
continueLine = false;
} else {
parameter[counter] = inBuffer[0];
counter++;
if (bResult && bytesRead == 0) {
continueLinea = false;
}
}
}
parameter[counter] = '\0';
memcpy(buffer, parameter, 256);
return 1;
}
By debugging, I know that the connectionType attribute ends up being a null terminated string "3", but the strcmp method keeps returning 3328 (>0). Is there a problem because "3" is a constant? What might be the problem?
I realized what was the problem with the code. The problem was that connectionType, whose value was a null terminated string "3", was in fact different to the line read from the file, which was actually a "3" plus a carriage return plus a null.
After I added that consideration to the code, my problem was solved.

shell execute with c++

I am working on an application that will trigger a UAC prompt in whatever program is opened by ShellExecute.
I can't figure out how to hard-code a path for the ShellExecute to run. As of now this program uses whatever path is in arg[0]. How can I build a string to put in the place of arg[0] on the line sinfo.lpFile = arg[0];?
I am very new so if you can't see why making a string to put in that line will solve my problem then you are most likely right.
#include "stdafx.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <shellapi.h>
#include <process.h>
#include "uac-example.h"
int WINAPI WinMain(HINSTANCE inst, HINSTANCE prevInst,LPSTR cmdLine, int nCmdShow){
LPWSTR *arg;
int argc = 0;
HRESULT ret = SUCCESS;
WCHAR imagePath[MAXPATHLEN];
WCHAR workingDir[MAXPATHLEN];
WCHAR uacDir[MAXPATHLEN];
WCHAR uacRunningLockFilePath[MAXPATHLEN];
HANDLE uacRunningLockFileHandle = INVALID_HANDLE_VALUE;
WCHAR elevatedLockFilePath[MAXPATHLEN];
HANDLE elevatedLockFileHandle = INVALID_HANDLE_VALUE;
arg = CommandLineToArgvW(GetCommandLineW(),&argc);
//if(arg == NULL || argc < 2) {
// ERRORBOX("Missing required program arguments.\n\nUsage:\nuac-example.exe <working directory>");
// return FAILURE;
//}
GetModuleFileName(NULL, imagePath, MAXPATHLEN);
arg[0] = imagePath;
wcscpy_s((wchar_t *)uacDir, MAXPATHLEN, arg[1]);
_snwprintf_s(uacRunningLockFilePath, MAXPATHLEN, MAXPATHLEN,
_T("%s/") _T(RUNNING_LOCK_FILE), uacDir);
wcscpy_s(workingDir, MAXPATHLEN, imagePath);
WCHAR *slash = wcsrchr(workingDir, '\\');
wcscpy_s(slash, MAXPATHLEN, _T(""));
_snwprintf_s(elevatedLockFilePath, MAXPATHLEN, MAXPATHLEN,_T("%s/") _T(ELEVATE_LOCK_FILE), workingDir);
uacRunningLockFileHandle = CreateFileW(uacRunningLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE _ON_CLOSE,NULL);
if (uacRunningLockFileHandle == INVALID_HANDLE_VALUE) {
if (_waccess(elevatedLockFilePath, F_OK) == 0 &&
_wremove(elevatedLockFilePath) != 0) {
return FAILURE;
}
elevatedLockFileHandle = CreateFileW(elevatedLockFilePath,(GENERIC_READ | GENERIC_WRITE),0,NULL,OPEN_ALWAYS,FILE_FLAG_DELETE _ON_CLOSE,NULL);
if(elevatedLockFileHandle == INVALID_HANDLE_VALUE){
ERRORBOX("Unable to acquire the necessary permissions to run demo app.");
return FAILURE;
}
LPWSTR spawnCmdLine = BuildCommandLine(argc - 1, arg + 1);
if(!spawnCmdLine){
CloseHandle(elevatedLockFileHandle);
ERRORBOX("An error occured while respawning self.");
return FAILURE;
}
SHELLEXECUTEINFO sinfo;
memset(&sinfo, 0, sizeof(SHELLEXECUTEINFO));
sinfo.cbSize = sizeof(SHELLEXECUTEINFO);
sinfo.fMask = SEE_MASK_FLAG_DDEWAIT | SEE_MASK_NOCLOSEPROCESS;
sinfo.hwnd = NULL;
sinfo.lpFile = arg[0];
sinfo.lpParameters = spawnCmdLine;
sinfo.lpVerb = L"runas"; // <<-- this is what makes a UAC prompt show up
sinfo.nShow = SW_SHOWMAXIMIZED;
BOOL result = ShellExecuteEx(&sinfo);
LocalFree(spawnCmdLine);
if(result){
WaitForSingleObject(sinfo.hProcess, INFINITE);
CloseHandle(sinfo.hProcess);
return SUCCESS;
}else{
return FAILURE;
}
}
EXIT_IF_ELEVATED(elevatedLockFilePath,uacRunningLo ckFileHandle,SUCCESS);
LocalFree(arg);
return SUCCESS;
}
// ----------------------------------------------------------------------
// The following code was taken directly from the Mozilla Firefox Updater
// source tree, and slightly modified to support "Wide" strings in
// Visual C++.
// ----------------------------------------------------------------------
LPWSTR
BuildCommandLine(int argc, LPWSTR *argv){
int i;
int len = 0;
// The + 1 of the last argument handles the
// allocation for null termination
for (i = 0; i < argc; ++i) {
len += ArgStrLen(argv[i]) + 1;
}
// Protect against callers that pass 0 arguments
if (len == 0) {
len = 1;
}
LPWSTR s = (LPWSTR)malloc(len * sizeof(LPWSTR));
if (!s) {
return NULL;
}
LPWSTR c = s;
for (i = 0; i < argc; ++i) {
c = ArgToString(c, argv[i]);
if (i + 1 != argc) {
*c = ' ';
++c;
}
}
*c = '\0';
return s;
}
int
ArgStrLen(LPWSTR s) {
int backslashes = 0;
int i = wcslen(s);
BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
if (addDoubleQuotes) {
i += 2; // initial and final duoblequote
}
if (hasDoubleQuote) {
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes preceding the doublequote
i += backslashes + 1;
}
backslashes = 0;
}
++s;
}
}
return i;
}
LPWSTR
ArgToString(LPWSTR d, LPWSTR s) {
int backslashes = 0;
BOOL hasDoubleQuote = wcschr(s, L'"') != NULL;
// Only add doublequotes if the string contains a space or a tab
BOOL addDoubleQuotes = wcspbrk(s, L" \t") != NULL;
if (addDoubleQuotes) {
*d = '"'; // initial doublequote
++d;
}
if (hasDoubleQuote) {
int i;
while (*s) {
if (*s == '\\') {
++backslashes;
} else {
if (*s == '"') {
// Escape the doublequote and all backslashes\
// preceding the doublequote
for (i = 0; i <= backslashes; ++i) {
*d = '\\';
++d;
}
}
backslashes = 0;
}
*d = *s;
++d; ++s;
}
} else {
wcscpy(d, s);
d += wcslen(s);
}
if (addDoubleQuotes) {
*d = '"'; // final doublequote
++d;
}
return d;
}
Simply as:
char path[] = "C:\\program.exe";
sinfo.lpFile = path;

Resources