Making directory with vitual studio 2012 coding in c++ - c++

Good evening everyone, please I'm writing a Library management application in c++ using virtual studio 2012. I had already writing some codes using Dev c++ it worked but when I switched to visual studio it gives error. It involves creating folders and checking if the folders were actually created. That is using dir and mkdir.

Windows and Linux (POSIX) don't support the same API for most file system functions. You can use Microsoft's platform-specific APIs like CreateDirectory() or use the POSIX-like versions like _mkdir().
If you have a more recent C++ compiler / standard library, you can use the experimental filesystem library that is slated to become part of standard C++, perhaps as early as C++17. If not, you can use Boost.Filesystem from which the pre-standard experimental library was drawn.
Here's a complete, minimal example using Boost.Filesystem, which will work on both Windows and Linux without modification:
#include <iostream>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
int main()
{
if( !fs::exists( "my_dir" ) )
{
if( fs::create_directory( "my_dir" ) )
{
std::cout << "Directory created!\n";
}
}
}
See it run: Coliru.
Here's the same code but with std::experimental::filesystem: Coliru.
You would need the appropriate include and linker paths setup in your build system for either of these to work locally. The biggest "gotcha" using the filesystem is that it throws exceptions for a lot of errors by default. You can either setup try/catch blocks at the appropriate places or pass in an error code param to make it return the status there instead.

#include <stdio.h>
#include <windows.h>
int main() {
if (!CreateDirectoryA("C:\\ABC123", NULL))
{
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
printf("Already Exists");
}else if (GetLastError()== ERROR_PATH_NOT_FOUND)
{
printf("Path not found");
}
}else{
printf("Created..");
}
}
simple function will do.

Thanks alot guys but I found this that solved my problem
#include <iostream>
#include <direct.h>
#include <stdlib.h>
#include <stdio.h>
using namespace std;
void main( void )
{
if( _mkdir( "\\testtmp" ) == 0 )
{
printf( "Directory '\\testtmp' was successfully created\n" );
system( "dir \\testtmp" );
if( _rmdir( "\\testtmp" ) == 0 )
printf( "Directory '\\testtmp' was successfully removed\n" );
else
printf( "Problem removing directory '\\testtmp'\n" );
}
else
printf( "Problem creating directory '\\testtmp'\n" );
int a;
cin >> a;
}
the cin >> a; is just to keep the output screen so I can see the result

Related

WinAPI FileExists Function Implemetation

I am coding a simple replacement for std::filesystem::exists() function using Windows API. Surprisingly, it turned out to be pretty hard. I want to keep my code simple, so I am using minimum functions. My function of choice is GetFileAttributesW(). Code is tested with fs::recursive_directory_iterator() function. My function thinks that all files in “C:\Windows\servicing\LCU*” don’t exist (ERROR_PATH_NOT_FOUND). This directory is responsible for storing Windows Update Caches and is famous for having extremely long file names. I couldn’t find anything else about this directory. Example of filenames and my code are included below. Hope this helps!
Edited:
The solution to this problem is to prepend absolute file path with “\\?\” char sequence. It makes Windows handle short files correctly!
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-16_altform-unplated_contrast-black.png
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-16_altform-unplated_contrast-white.png
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-20_altform-unplated_contrast-black.png
C:\Windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2006.1.7\amd64_microsoft-windows-a..g-whatsnew.appxmain_31bf3856ad364e35_10.0.19041.1741_none_ee5d4a8d060d7653\f\new360videossquare44x44logo.targetsize-20_altform-unplated_contrast-white.png
#include <windows.h>
#include <filesystem>
#include <iostream>
#include <string>
using namespace std;
namespace fs = std::filesystem;
int FileExists(wstring file_path) {
/* TODO:
1. Doesn't work with "C:\\Windows\\servicing\\LCU\\*".
2. Improve error system.
*/
DWORD attributes = GetFileAttributesW(file_path.c_str());
// Valid attributes => File exists
if (attributes != INVALID_FILE_ATTRIBUTES) {
return true;
}
DWORD error_code = GetLastError();
wcout << error_code << ' ' << file_path << '\n';
// Path related error => File doesn't exist
if (error_code == ERROR_PATH_NOT_FOUND || error_code == ERROR_INVALID_NAME ||
error_code == ERROR_FILE_NOT_FOUND || error_code == ERROR_BAD_NETPATH)
{
return false;
}
// Other errors are logged before if statement
// File is busy with IO operations, etc.
return error_code;
}
int main() {
for (fs::path path : fs::recursive_directory_iterator("C:\\", fs::directory_options::skip_permission_denied)) {
FileExists(path);
}
return 0;
}
The solution that worked for me is to prepend absolute file path with “\\?\” char sequence. Somehow, it makes Windows handle shortened file paths correctly!
Check out MSDN Article "Maximum File Path Limitation" for more info.

Cannot write an array in a Ubuntu device using C++ (Debug Assertion Failed. Expression (stream !=NULL))

I am working on Windows and I am trying to write an array into a Ubuntu device using C++ in Visual Studio 2019. Here's a sample of my code:
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs, int *iAnsSize, char *sAns)
...
...
...
char pcFolderName[256];
char pcFileName[256];
sprintf(pcFolderName, "%s\\%s",pcSavePath, pcUUTSerialNumber);
sprintf(pcFileName, "%s\\calib_rfclock.conf",pcFolderName);
// WRITE TABLE ON PC
FILE *pFileW;
pFileW = fopen(pcFileName,"wb");
fwrite(&CalibTable, sizeof(char), CalibTable.hdr.v1.u32Len, pFileW);
fclose(pFileW);
}
return 0;
However, I keep having this pop-up from Microsoft Visual C++ Debug Library that says:
Debug Assertion Failed:
Program:...
File: f:\dd\vctools\crt_bld\sefl_x86\crt\src\fwrite.c
Line: 77
Expression: (stream != NULL)
...
I found this thread and I tried logging in as root on my Ubuntu device. I also tried:
mount -o remount,rw /path/to/parent/directory
chmod 777 /path/to/parent/directory
And I can also create/edit manualy any file in the directory I'm trying to write into with my code, but I get the same error when running it.
Anyone knows what could cause this? I think it could be on the Windows side, but I don't know what I am doing wrong. Thanks a lot in advance.
You never check that opening the file succeeds - and it most likely fails, which is why you get the debug pop-up. Your use of \ as directory delimiters may be the only reason why it fails, but you should check to be sure.
I suggest that you use std::filesystem::path (C++17) to build your paths. That makes it easy to create paths in a portable way. You could also make use of a C++ standard std::ofstream to create the file. That way you don't need to close it afterwards. It closes automatically when it goes out of scope.
Example:
#include <cerrno>
#include <cstring>
#include <filesystem>
#include <fstream>
int Run_WriteCalibTable(char *pcIPAddress, int iNumArgs, float *fArgs,
int *iAnsSize, char *sAns)
{
...
// Build std::filesystem::paths:
auto pcFolderName = std::filesystem::path(pcSavePath) / pcUUTSerialNumber;
auto pcFileName = pcFolderName / "calib_rfclock.conf";
// only try to write to the file if opening the file succeeds:
if(std::ofstream pFileW(pcFileName, std::ios::binary); pFileW) {
// Successfully opened the file, now write to it:
pFileW.write(reinterpret_cast<const char*>(&CalibTable),
CalibTable.hdr.v1.u32Len);
} else {
// Opening the file failed, print the reason:
std::cerr << pcFileName << ": " << std::strerror(errno) << std::endl;
}
...
}

How to search and move files from one path to another C++?

I'm trying to search all files that follow this pattern "console-*" and move them to another path on my machine if they exist. (For example from: /documents/fs/pstore to /sdk/sys/kernel_dump/).
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
int dirExists(const char *pathname)
{
struct stat info;
if( stat( pathname, &info ) != 0 )
return 0; // printf( "cannot access %s\n", pathname );
else if( info.st_mode & S_IFDIR ) // S_ISDIR() doesn't exist on my windows
return 1; // printf( "%s is a directory\n", pathname );
else
return 0; // printf( "%s is no directory\n", pathname );
}
int main()
{
const char *path = "/documents/fs/pstore";
if(dirExists(path))
system("mv /documents/fs/pstore/console-* /sdk/sys/kernel_dump/ ");
else
printf( "error" );
return 0;
}
I've experienced with the code above, but it does not seem to work properly, should I try another approach, maybe with the rename() function? (I'm working on Linux)
Any advice would be greatly appreciated, thank you in advance.
You can call glob() and rename() C functions in Linux if C++17's std::filesystem is not an option for you. glob() gives you the list of files that matches globbing pattern like *, ? and []. However, rename() may fail if the mount position of from and to path are not identical. In this case, you should create your own copy and remove file function.

nVidia driver version from WMI is not what I want

I want to get driver version of nVidia video card.
So I used WMI and get data from "DriverVersion" obejct of "Win32_VideoController" class.
But it was like "9.18.13.1106"(file version) and what I wanted is something like "311.06"(treiber version).
Where can I get that information?
If it is impossible on WMI, I want to know other way to get that.
Thanks.
You can do this using NVML from nVidia's Tesla Deployment Kit. You can retrieve the internal driver version (the one you're accustomed to seeing for an nVidia driver) with code like this:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <nvml.h>
#include <windows.h>
namespace {
typedef nvmlReturn_t (*init)();
typedef nvmlReturn_t (*shutdown)();
typedef nvmlReturn_t (*get_version)(char *, unsigned);
class NVML {
init nvmlInit;
shutdown nvmlShutdown;
get_version nvmlGetDriverVersion;
std::string find_dll() {
std::string loc(getenv("ProgramW6432"));
loc += "\\Nvidia Corporation\\nvsmi\\nvml.dll";
return loc;
}
public:
NVML() {
HMODULE lib = LoadLibrary(find_dll().c_str());
nvmlInit = (init)GetProcAddress(lib, "nvmlInit");
nvmlShutdown = (shutdown)GetProcAddress(lib, "nvmlShutdown");
nvmlGetDriverVersion = (get_version)GetProcAddress(lib, "nvmlSystemGetDriverVersion");
if (NVML_SUCCESS != nvmlInit())
throw(std::runtime_error("Unable to initialize NVML"));
}
std::string get_ver() {
char buffer[81];
nvmlGetDriverVersion(buffer, sizeof(buffer));
return std::string(buffer);
}
~NVML() {
if (NVML_SUCCESS != nvmlShutdown())
throw(std::runtime_error("Unable to shut down NVML"));
}
};
}
int main() {
std::cout << "nVidia Driver version: " << NVML().get_ver();
}
Note that if you're writing this purely for your own use on a machine where you're free to edit the PATH, you can simplify this quite a bit. Most of the code deals with the fact that this uses NVML.DLL, which is in a directory that's not normally on the path, so the code loads that dynamically, and uses GetProcAddress to find the functions in it that we need to use. In this case, we're only using three functions, so it's not all that difficult to deal with, but it still at drastically increases the length of the code.
If we could ignore all that nonsense, the real code would just come out to something on this general order:
nvmlInit();
nvmlSystemGetDriverVersion(result, sizeof(result));
std::cout << result;
nvmlShutdown();
Anyway, to build it, you'll need a command line something like:
cl -Ic:\tdk\nvml\include nv_driver_version.cpp
...assuming you've installed the Tesla Deployment Kit at c:\tdk.
In any case, yes, I've tested this to at least some degree. On my desktop it prints out:
nVidia Driver version: 314.22
...which matches what I have installed.
To get the Nvidia driver version through C++ on Win64:
Download NVAPI https://developer.nvidia.com/rtx/path-tracing/nvapi/get-started, a few MB
The main folder of the downloaded archive contains several header files, one of which is nvapi.h. Those headers are needed for compilation. The subfolder amd64 contains nvapi64.lib, which is needed for linking. The following code will now show the driver version:
#include <iostream>
extern "C" {
#include "nvapi.h"
}
int main() {
NvAPI_Status status = NVAPI_OK;
NvAPI_ShortString str;
status = NvAPI_Initialize();
if (status == NVAPI_LIBRARY_NOT_FOUND) {
//in this case NvAPI_GetErrorMessage() will only return an empty string
std::printf("error no nvidia driver found\n");
} else if (status != NVAPI_OK) {
NvAPI_GetErrorMessage(status, str);
std::printf("error initializing nvapi: %s\n", str);
}
NvU32 version = 0;
NvAPI_ShortString branch;
status = NvAPI_SYS_GetDriverAndBranchVersion(&version, branch);
if (status != NVAPI_OK) {
NvAPI_GetErrorMessage(status, str);
std::printf("error getting driver version: %s\n", str);
} else {
std::printf("driver version %d.%d", version / 100, version % 100);
}
}

C++ - Determining if directory (not a file) exists in Linux [duplicate]

This question already has answers here:
Checking if a directory exists in Unix (system call)
(5 answers)
Closed 4 years ago.
How would I determine if a directory (not a file) existed using C++ in Linux? I tried using the stat() function but it returned positive when a file was found. I only want to find if the inputted string is a directory, not something else.
According to man(2) stat you can use the S_ISDIR macro on the st_mode field:
bool isdir = S_ISDIR(st.st_mode);
Side note, I would recommend using Boost and/or Qt4 to make cross-platform support easier if your software can be viable on other OSs.
how about something i found here
#include <dirent.h>
bool DirectoryExists( const char* pzPath )
{
if ( pzPath == NULL) return false;
DIR *pDir;
bool bExists = false;
pDir = opendir (pzPath);
if (pDir != NULL)
{
bExists = true;
(void) closedir (pDir);
}
return bExists;
}
Or using stat
struct stat st;
if(stat("/tmp",&st) == 0)
if(st.st_mode & S_IFDIR != 0)
printf(" /tmp is present\n");
If you can check out the boost filesystem library. It's a great way to deal with this kind of problems in a generic and portable manner.
In this case it would suffice to use:
#include "boost/filesystem.hpp"
using namespace boost::filesystem;
...
if ( !exists( "test/mydir" ) ) {bla bla}
The way I understand your question is this: you have a path, say, /foo/bar/baz (baz is a file) and you want to know whether /foo/bar exists. If so, the solution looks something like this (untested):
char *myDir = dirname(myPath);
struct stat myStat;
if ((stat(myDir, &myStat) == 0) && (((myStat.st_mode) & S_IFMT) == S_IFDIR)) {
// myDir exists and is a directory.
}
In C++17**, std::filesystem provides two variants to determine the existence of a path:
is_directory() determines, if a path is a directory and does exist in the actual filesystem
exists() just determines, if the path exists in the actual filesystem (not checking, if it is a directory)
Example (without error handling):
#include <iostream>
#include <filesystem> // C++17
//#include <experimental/filesystem> // C++14
namespace fs = std::filesystem;
//namespace fs = std::experimental::filesystem; // C++14
int main()
{
// Prepare.
const auto processWorkingDir = fs::current_path();
const auto existingDir = processWorkingDir / "existing/directory"; // Should exist in file system.
const auto notExistingDir = processWorkingDir / "fake/path";
const auto file = processWorkingDir / "file.ext"; // Should exist in file system.
// Test.
std::cout
<< "existing dir:\t" << fs::is_directory(existingDir) << "\n"
<< "fake dir:\t" << fs::is_directory(notExistingDir) << "\n"
<< "existing file:\t" << fs::is_directory(file) << "\n\n";
std::cout
<< "existing dir:\t" << fs::exists(existingDir) << "\n"
<< "fake dir:\t" << fs::exists(notExistingDir) << "\n"
<< "existing file:\t" << fs::exists(file);
}
Possible output:
existing dir: 1
fake dir: 0
existing file: 0
existing dir: 1
fake dir: 0
existing file: 1
**in C++14 std::experimental::filesystem is available
Both functions throw filesystem_error in case of errors. If you want to avoid catching exceptions, use the overloaded variants with std::error_code as second parameter.
#include <filesystem>
#include <iostream>
namespace fs = std::filesystem;
bool isExistingDir(const fs::path& p) noexcept
{
try
{
return fs::is_directory(p);
}
catch (std::exception& e)
{
// Output the error message.
const auto theError = std::string{ e.what() };
std::cerr << theError;
return false;
}
}
bool isExistingDirEC(const fs::path& p) noexcept
{
std::error_code ec;
const auto isDir = fs::is_directory(p, ec);
if (ec)
{
// Output the error message.
const auto theError = ec.message();
std::cerr << theError;
return false;
}
else
{
return isDir;
}
}
int main()
{
const auto notExistingPath = fs::path{ "\xa0\xa1" };
isExistingDir(notExistingPath);
isExistingDirEC(notExistingPath);
}
If you want to find out whether a directory exists because you want to do something with it if it does (create a file/directory inside, scan its contents, etc) you should just go ahead and do whatever you want to do, then check whether it failed, and if so, report strerror(errno) to the user. This is a general principle of programming under Unix: don't try to figure out whether the thing you want to do will work. Attempt it, then see if it failed.
If you want to behave specially if whatever-it-was failed because a directory didn't exist (for instance, if you want to create a file and all necessary containing directories) you check for errno == ENOENT after open fails.
I see that one responder has recommended the use of boost::filesystem. I would like to endorse this recommendation, but sadly I cannot, because boost::filesystem is not header-only, and all of Boost's non-header-only modules have a horrible track record of causing mysterious breakage if you upgrade the shared library without recompiling the app, or even if you just didn't manage to compile your app with exactly the same flags used to compile the shared library. The maintenance grief is just not worth it.