-1

I'm a little bit confused with that, but I cant understand why one code is working and another isn't.. Seems like it's the same, but largest one cathes and error in the string with calling function "GetFileAttributes". The first code is not working.

#include "stdafx.h"
#include <iostream>
#include <Windows.h>
#include <stdio.h>
#include <conio.h>

using namespace std;


int _tmain(int argc, _TCHAR* argv[]) {
    if (argc < 2){
        char answer;
        do
        {
            cout << "You didn't type in the path to the file. Do you want to do it now? [y/n]" << endl;
            cin >> answer;
        } while (!cin.fail() && answer != 'y' && answer != 'Y' && answer != 'n' && answer != 'N');
        cin.clear();
        if (answer == 'N' || answer == 'n'){
            return 0;
        }
        printf("%s", "Type in the path to the file\n");
        scanf("%s", (argv + 1));
    }
    //LPCWSTR l = (LPCWSTR) (argv+1);
    DWORD d = GetFileAttributes(argv[1]);
    printf("%s", "Attrbiutes for this file are\n");
    if (d == INVALID_FILE_ATTRIBUTES){
        printf("%s", "Invalid attributes\n");
    }
    if (d & FILE_ATTRIBUTE_ARCHIVE){
        printf("%s", "Archive\n");
    }
    if (d & FILE_ATTRIBUTE_COMPRESSED){
        printf("%s", "Compressed\n");
    }
    if (d & FILE_ATTRIBUTE_DIRECTORY){
        printf("%s", "Directory\n");
    }
    if (d & FILE_ATTRIBUTE_HIDDEN){
        printf("%s", "Hidden\n");
    }
    if (d & FILE_ATTRIBUTE_READONLY){
        printf("%s", "Read-only\n");
    }
    _getch();
    return 0;
}

Here is the working one

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <conio.h>

int _tmain(int argc, _TCHAR* argv[])
{
    DWORD x = GetFileAttributes(argv[1]);

    if (x == INVALID_FILE_ATTRIBUTES)
    {
        std::cout << "error" << std::endl;
        return 0;
    }

    if (x & FILE_ATTRIBUTE_ARCHIVE)
    {
        std::cout << "archive" << std::endl;
    }

    if (x & FILE_ATTRIBUTE_HIDDEN)
    {
        std::cout << "hidden" << std::endl;
    }

    if (x & FILE_ATTRIBUTE_READONLY)
    {
        std::cout << "read only" << std::endl;
    }

    if (x & FILE_ATTRIBUTE_SYSTEM)
    {
        std::cout << "system" << std::endl;
    }

    if (x & FILE_ATTRIBUTE_TEMPORARY)
    {
        std::cout << "temporary" << std::endl;
    }
    _getch();
    return 0;
}
mboronin
  • 875
  • 1
  • 10
  • 16
  • I don't really understand what you're asking. Describe your problem further. – vmg Nov 26 '14 at 17:06
  • One code is working, other isn't. Why? – mboronin Nov 26 '14 at 17:11
  • If the first code isn´t working, take the second one. ... [sarcasm turned off] They don´t look equal to me, neither in code nor behaviour. So what do you want to do? – deviantfan Nov 26 '14 at 17:12
  • 1
    a) You´re using printf rather strangely. b) Filling argv with own content is not allowed. c) In case of INVALID_FILE_ATTRIBUTES, the first code is missing the return. d) Always check argc before using argv. e) Don´t use _tmain and TCHAR etc. f) Don´t use conio.h. g) scanf with %s has a problem with blanks. h) Don´t mix C and C++. – deviantfan Nov 26 '14 at 17:13
  • @deviantfan Why fiiling argv is not allowed? – mboronin Nov 26 '14 at 17:20
  • @deviantfan you say filling argv is not allowed and then ask to check argc before using argv – mboronin Nov 26 '14 at 17:21
  • @user2897208 You´re allowed to read the argv values, but not write to the variable. Why? Because that´s how it is. If you want another reason: Do you know how much memory the OS reserved, ie. how many chars will fit in? No. If you save more than reserved, your program got a problem (crash or some strange unexplainable behaviour) – deviantfan Nov 26 '14 at 17:23
  • Whoops, correction: It´s indeed allowed, but there is still the problem with the reserved size. – deviantfan Nov 26 '14 at 17:27
  • 1
    "isn't working" is not a useful problem description, and neither is "cathes and error" (which I presume was meant to be "causes an error"), because you fail to include information on what the "error" is. If you want help, include the relevant information and ask a **specific** question. – Ken White Nov 26 '14 at 17:40

1 Answers1

0

This is not the right way to use argv. DO NOT MODIFY IT. Treat it as read-only. Use a separate variable to hold the filename, prompting the user to populate that variable if needed, and then use the variable instead of argv when using the filename.

Also, new OS version introduce new file attributes, which you are not taking into account. You should output all attributes, even ones you do not recognize.

Also, you should stop mixing C and C++ I/O. Pick one or the other and be consistent with it.

Try something more like this:

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

int _tmain(int argc, _TCHAR* argv[])
{
    std::string filename;
    char ch;

    if (argc >= 2)
    {
        filename = argv[1];
    }
    else
    {
        do
        {
            std::cout << "You didn't provide a path to the file. Do you want to type it now? [y/n]" << std::endl;
            if (!(std::cin >> ch))
                return 0;
        }
        while ((ch != 'y') && (ch != 'Y') && (ch != 'n') && (ch != 'N'));
        if ((ch == 'N') || (ch == 'n'))
            return 0;
        cin.clear();
        do
        {
            std::cout << "Type in the path to the file" << std::endl;
            if (!std::getline(std::cin, filename))
                return 0;
        }
        while (filename.empty());
    }

    DWORD d = GetFileAttributesA(filename.c_str());
    std::cout << "Attributes for file: " << filename << std::endl;

    if (d == INVALID_FILE_ATTRIBUTES)
    {
        std::cout << "Invalid attributes" << std::endl;
    }
    else
    {
        if (d & FILE_ATTRIBUTE_ARCHIVE)
        {
            std::cout << "Archive" << std::endl;
            d &= ~FILE_ATTRIBUTE_ARCHIVE;
        }
        if (d & FILE_ATTRIBUTE_COMPRESSED)
        {
            std::cout << "Compressed" << std::endl;
            d &= ~FILE_ATTRIBUTE_COMPRESSED;
        }
        if (d & FILE_ATTRIBUTE_DIRECTORY)
        {
            std::cout << "Directory" << std::endl;
            d &= ~FILE_ATTRIBUTE_DIRECTORY;
        }
        if (d & FILE_ATTRIBUTE_HIDDEN)
        {
            std::cout << "Hidden" << std::endl;
            d &= ~FILE_ATTRIBUTE_HIDDEN;
        }
        if (d & FILE_ATTRIBUTE_READONLY)
        {
            std::cout << "Read-only" << std::endl;
            d &= ~FILE_ATTRIBUTE_READONLY;
        }
        if (d != 0)
        {
            std::cout << "Other: " << std::hex << std::showbase << std::setw(8) << std::setfill('0') << d << std::endl;
        }
    }

    std::cout << "Press a key to exit" << std::endl;
    std::cin >> ch;

    return 0;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770