Can't pass argv into a string in one project; Works fine in another

874 Views Asked by At

I have two c++ win32 console application project. Both have exactly identical code.

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc != 3){

        cout << "Program needs 2 arguments";
    }
    else{
        string filePath = argv[1];
        string flag = argv[2];
        unsigned long int size;
        bool najden = false;

        //odpri datoteko
        ifstream idatoteka(filePath, ios::in | ios::binary | ios::ate);
        if (idatoteka){
            if (flag != "-c" && flag != "-e"){
                cout << "unknown flag";
            }
            else{
                if (flag == "-c"){
                    //kompresija
                }
                else{
                    //dekompresija
                }
            }
        }
        else{
            cout << "This file doesn't exist\n";
        }
    }
    system("pause");
    return 0;
}

The silly thing is that one of them is giving me an error where I try to pass argv[1] and argv[2] into string variables. The error message is as follows:

cannot convert from '_TCHAR *' to 'std::basic_string<char,std::char_traits<char>,std::allocator<char>>'

Since when doesn't this work and how can one of two identical projects possibly generate an error?

1

There are 1 best solutions below

0
On BEST ANSWER

_TCHAR is either defined as wchar_t or char depending on whether the project is set to compile for Unicode or not. When you have a project being compiled for Ansi/MBCS, _TCHAR* (ie char*) can be assigned to std::string. When you have a project being compiled for Unicode instead, _TCHAR* (ie wchar_t*) cannot be assigned to std::string, you have to use std::wstring instead, or convert the Unicode data to Ansi/MBCS at runtime.

If you really want the same code to compile in both configurations, you will have to use std::basic_string<_TCHAR> and std::basic_ifstream<_TCHAR>, wrap literals in _T(), etc. For example:

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int _tmain(int argc, _TCHAR* argv[])
{
    if (argc != 3){
        cout << "Program needs 2 arguments";
    }
    else{
        basic_string<_TCHAR> filePath = argv[1];
        basic_string<_TCHAR> flag = argv[2];
        unsigned long int size;
        bool najden = false;

        //odpri datoteko
        basic_ifstream<_TCHAR> idatoteka(filePath, ios::in | ios::binary | ios::ate);
        if (idatoteka){
            if (flag != _T("-c") && flag != _T("-e")){
                cout << "unknown flag";
            }
            else{
                if (flag == _T("-c")){
                    //kompresija
                }
                else{
                    //dekompresija
                }
            }
        }
        else{
            cout << "This file doesn't exist\n";
        }
    }
    system("pause");
    return 0;
}

Windows has been a Unicode OS for a LONG LONG time. Using _TCHAR only makes sense if you are developing for Windows 9x/ME. Otherwise, you really should be using Unicode only and not _TCHAR at all:

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int wmain(int argc, WCHAR* argv[])
{
    if (argc != 3){
        wcout << L"Program needs 2 arguments";
    }
    else{
        wstring filePath = argv[1];
        wstring flag = argv[2];
        unsigned long int size;
        bool najden = false;

        //odpri datoteko
        wifstream idatoteka(filePath, ios::in | ios::binary | ios::ate);
        if (idatoteka){
            if (flag != L"-c" && flag != L"-e"){
                wcout << L"unknown flag";
            }
            else{
                if (flag == L"-c"){
                    //kompresija
                }
                else{
                    //dekompresija
                }
            }
        }
        else{
            wcout << L"This file doesn't exist\n";
        }
    }
    system("pause");
    return 0;
}