Having a issue while iterating all files and folders recursively in C++ - c++

I have the following code to iterate all the files and folders on all the drives on a system. Can you help me please understand what is missing ? I'm getting an exception for fs::recursive_directory_iterator. Thanks !
#include <iostream>
#include <Windows.h>
#include <vector>
#include <string>
#include <filesystem>
namespace fs = std::filesystem;
std::vector<std::string> getDrive() {
std::vector<std::string> Drives;
char* lDrives = new char[MAX_PATH]();
if (GetLogicalDriveStringsA(MAX_PATH, lDrives))
{
for (int i = 0; i < 100; i += 4)
{
if (lDrives[i] != (char)0)
{
Drives.push_back(std::string{ lDrives[i],lDrives[i + 1],lDrives[i + 2] });
}
}
}
delete[] lDrives;
return Drives;
}
int main()
{
std::vector<std::string> diskdrives = getDrive();
for (auto drv : diskdrives) {
for (auto& file : fs::recursive_directory_iterator(drv)) {
try {
if (fs::is_directory(file))
{
}
else
{
std::cout << file.path().string() << std::endl;
}
}
catch (const std::exception&)
{
}
}
}
}

Related

why have i bus error 10, when I put cout<<""<<endl; out of my code

I have written a code, but there’s one Problem. When I put cout<<""<<endl; out, I have Bus error: 10. How can I solve this Problem.
This is my code:
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <cstdlib>
#include <cstring>
#include <cstdlib>
#include <cstring>
#include <assert.h>
#include <ctime>
#include <sstream>
#include <iostream>
#include <iomanip>
using namespace std;
char* rotate(char const* a, int b)
{
char* r;
for (int i = 0; i < int(strlen(a)); i++) {
if (i >= int(strlen(a)) - b) {
r[i] = a[i - int(int(strlen(a)) - b)];
}
else if (i + b < 0) {
r[i] = a[int(strlen(a) + b)];
}
else {
r[i] = a[i + b];
}
}
r[int(strlen(a))] = '\0';
return r;
}
char* Crypt(char* Input, bool Encrypt, int InitialRotation, int Rotation)
{
char const* Table;
try {
Table = new char[size_t(strlen(Table))];
}
catch (...) {
throw "No Memory";
};
char* a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
try {
a = new char[size_t(strlen(a))];
}
catch (...) {
throw "No Memory";
};
char* ActualTable;
try {
ActualTable = new char[size_t(strlen(ActualTable))];
}
catch (...) {
throw "No Memory";
};
int Offset = InitialRotation;
char* Result;
try {
Result = new char[size_t(strlen(Result))];
}
catch (...) {
throw "No Memory";
};
int b;
Table = "JPGVOUMFYQBENHZRDKASXLICTW";
a = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for (int i = 0; i < int(strlen(Input)); i++) {
for (int c = 0; i < int(strlen(a)); c++) {
if (a[c] == Input[i]) {
b = c;
break;
}
}
cout << "" << endl;
ActualTable = rotate(Table, Offset);
Result[i] = rotate(Table, Offset)[b];
Offset = Offset + Rotation;
}
return Result;
}
int main()
{
char* A = "ZZZZ";
cout << Crypt(A, 1, 1, 4) << endl;
return 0;
}

Iterate a string until int or char

I want to make to two vectors from a string.
from :
std::string input = "82aw55beA1/de50Ie109+500s";
to :
std::vector<int> numbers = {82,55,1,50,109,500};
std::vector<char> notNumbers = {'a','w','b','e','A','/','d','e','I','e','+','s'};
How do I do this in the most efficient time complexitie?
You can make one pass over the string. You need to know if you're currently parsing a digit or not, whether you're "in" a number, and the current number you're in.
It's a pretty straightforward process, but if you have questions, please ask.
#include <string>
#include <vector>
#include <iostream>
#include <cctype>
int main() {
std::string input = "82aw55beA1/de50Ie109+500s";
std::vector<int> numbers;
std::vector<char> notNumbers;
int currentNumber = 0;
bool inNumber = false;
for (auto ch : input) {
if (std::isdigit(ch)) {
if (!inNumber) {
currentNumber = 0;
inNumber = true;
}
currentNumber = currentNumber * 10 + (ch - '0');
}
else {
if (inNumber) {
numbers.push_back(currentNumber);
inNumber = false;
}
notNumbers.push_back(ch);
}
}
if (inNumber) {
numbers.push_back(currentNumber);
}
for (auto i : numbers) {
std::cout << i << std::endl;
}
for (auto ch : notNumbers) {
std::cout << ch << std::endl;
}
}

How would I make my code run when I press a button?

So I'm fairly new to c++ and coding in general, and I tried making a test code that would run when I press a button.
I tried changing for loop to a while loop, but that doesn't help.
Here's what I came up with:
#include <iostream>
#include <Windows.h>
int main() {
int i{ 0 };
bool condition = false;
if (GetAsyncKeyState(VK_HOME)) {
condition = true;
}
for (; condition;) {
std::cout << i << std::endl;
i++;
if (GetAsyncKeyState(VK_END)) {
condition = false;
}
}
}
I thought that the code would work, but the result is this:
The code runs, but it ends straight away...
Your solution, modified to use proper loops.
#include <iostream>
#include <Windows.h>
int main() {
while (!GetAsyncKeyState(VK_HOME))
;
for (size_t i {0}; !GetAsyncKeyState(VK_END); ++i)
std::cout << i << std::endl;
}
I think I found a fix, I tried using a goto statement, and it now works.
If you have a more efficient way, please post :D
#include <iostream>
#include <Windows.h>
int main() {
int i{ 0 };
bool condition = false;
start:
if (GetAsyncKeyState(VK_HOME)) {
condition = true;
}
else {
goto start;
}
while(condition) {
std::cout << i << std::endl;
i++;
if (GetAsyncKeyState(VK_END)) {
condition = false;
}
}
}

insert string into vector character by character

I'm trying to insert the characters of the string into a char vector but place the letters in reverse order . can anyone tell me why this doesn't work
int main()
{
string a = "Hello";
vector<char> arr(5);
for(int i = 4 ; i == 0 ; i--)
{
arr.push_back(a[i]);
cout << arr[i];
}
return 0;
}
im trying to push back the character in reverse order 1 by 1
Their are several problems with your code:
you are creating a vector whose size is initially 5, and then you are attempting to push 5 additional chars into it, for a total of 10 chars. You need to either:
initialize it's capacity instead of its size.
initialize the size as you are, but use arr[4-i] instead of arr.push_back() inside your loop.
your loop is never entered at all, since i == 0 is never true.
Try something more like this instead:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
size_t len = a.size();
vector<char> arr;
arr.reserve(len);
for(int i = len-1; i >= 0; i--) {
arr.push_back(a[i]);
}
for(size_t i = 0; i < len; ++i) {
cout << arr[i];
}
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
size_t len = a.size();
vector<char> arr(len);
for(int i = len-1; i >= 0; i--) {
arr[len-1-i] = a[i];
}
for(size_t i = 0; i < len; ++i) {
cout << arr[i];
}
return 0;
}
Another way to deal with this in a more C++-ish way is to use iterators instead:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr;
arr.reserve(a.size());
for(auto iter = a.rbegin(); iter != a.rend(); ++iter) {
arr.push_back(*iter);
}
for(auto ch : arr) {
cout << ch;
}
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr(a.size());
auto arr_iter = arr.begin();
for(auto a_iter = a.rbegin(); a_iter != a.rend(); ++a_iter, ++arr_iter) {
*arr_iter = *a_iter;
}
for(auto ch : arr) {
cout << ch;
}
return 0;
}
And then you can get rid of the manual loops altogether:
#include <iostream>
#include <string>
#include <vector>
#include <iterator>
#include <algorithm>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr;
arr.reserve(a.size());
copy(a.rbegin(), a.rend(), back_inserter(arr));
cout.write(arr.data(), arr.size());
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr(a.size());
copy(a.rbegin(), a.rend(), arr.begin());
cout.write(arr.data(), arr.size());
return 0;
}
Alternatively:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main() {
string a = "Hello";
vector<char> arr(a.rbegin(), a.rend());
cout.write(arr.data(), arr.size());
return 0;
}
I'm not sure why you're complicating matters when a vector is perfectly capable of taking an iterator in the constructor? The vast majority of your code can therefore be replaced with a simple:
vector<char> arr(a.rbegin(), a.rend());
The complete program below shows this in action:
#include <iostream>
#include <string>
#include <vector>
using std::cout; using std::string; using std::vector;
int main() {
string a = ")-: yug emosdnah a si xaP";
vector<char> arr(a.rbegin(), a.rend());
for (auto ch: arr) cout << ch;
cout << '\n';
}
for(int i = 4 ; i == 0 ; i--)
That means to keep going while i is equal to zero - but i starts out at four, so the for loop terminates immediately.
You probably meant
for(int i = 4 ; i >= 0 ; i--)

C++ Error C2451 conditional String is illegal

i'm fairly new to C++.
I want to write a Program/Function that checks a string input (from console or other source, not important here) if is already in an array. If it's not then it should be written into array. Otherwise do nothing.
My Problem is the for loop and if the if condition. What am I missing?
#include <iostream>
#include <string>
#include <fstream>
#include <stdio.h>
using namespace std;
typedef struct {
string id[10];
string foo1[10];
string type[10];
string func[10];
}Device;
int main() {
Device fooDevice;
string mystring;
int i = 0;
mystring = "foo";
ofstream temp;
temp.open("temp.txt", ios::out | ios::app);
for (fooDevice.id[i]; fooDevice.id[9]; i++) {
if (fooDevice.id[i] != mystring) {
fooDevice.id[i] = mystring;
temp << mystring << endl;
} else {
//do nothing
}
}
return 0;
}
The problem is the structure of your for loop. I'm not sure what you think your condition means, but here's how it should look:
for (std::size_t i = 0; i < 10; ++i) {
This increments the index value i from 0 to 9 (inclusive). You can then check the value of fooDevice[i].
At the moment, it seems you are trying to overwrite every element of the array with the new string. I'm not sure how you know how full the array is at any given time. Let's suppose you stop when you get to the first empty string:
for (std::size_t i = 0; i < 10; ++i) {
if (myString == fooDevice.id[i]) {
// already there, stop looping
break;
}
else if (fooDevice.id[i].empty()) {
// none of the currently set elements matches
fooDevice.id[i] = myString;
temp << myString << '\n';
break;
}
}
You could also replace this with a range-based-for:
for (auto& deviceId: fooDevice.id) {
if (myString == deviceId) {
// already there, stop looping
break;
}
else if (deviceId.empty()) {
// none of the currently set elements matches
deviceId = myString;
temp << myString << '\n';
break;
}
}
Better yet, use a std::vector with std::find from the <algorithm> header. (Warning: untested code):
struct Device {
// ...
std::vector<std::string> id;
// ...
};
// ...
auto foundId = std::find(fooDevice.id.begin(), fooDevice.id.end(), myString);
if (fooDevice.id.end() == foundId) {
// not already there
fooDevice.id.push_back(myString);
temp << myString << '\n';
}
It seems you are a bit confused about the difference between C and C++ as well:
The C++ version of <stdio.h> is <cstdio>, but you don't need it here at all (and you usually don't in a C++ program).
You don't need to typedef the name of a struct in C++, just do struct Device { ... };
And regarding C++ style, please reconsider your use of what are often considered bad practices: using namespace std; and endl.
for (fooDevice.id[i]; fooDevice.id[9]; i++) seems no scence. I think you want:
for(; i<9; ++i)
You can't use a string value as a loop condition. Only expressions that evaluate to booleans.
Also, you are also not initializing the device arrays before searching them.
Try something more like this:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
struct Device {
string id[10];
string foo1[10];
string type[10];
string func[10];
};
int main() {
Device fooDevice;
string mystring;
// fill fooDevice as needed...
mystring = "foo";
ofstream temp;
temp.open("temp.txt", ios::out | ios::app);
bool found = false;
int idx_available = -1;
for (int i = 0; i < 10; ++i) {
if (fooDevice.id[i] == mystring) {
//do nothing
found = true;
break;
}
if ((idx_available == -1) && fooDevice.id[i].empty())
idx_available = i;
}
if ((!found) && (idx_available != -1)) {
fooDevice.id[idx_available] = mystring;
temp << mystring << endl;
}
return 0;
}
Which would be better handled with some rewriting:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
struct Device {
std::string id;
std::string foo1;
std::string type;
std::string func;
};
struct isDeviceId {
const std::string &m_id;
isDeviceId(const std::string &id) : m_id(id) {
}
bool operator()(const Device &device) {
return (device.id == m_id);
}
};
int main() {
std::vector<Device> devices;
std::string mystring;
// fill devices as needed...
mystring = "foo";
if (std::find_if(devices.begin(), devices.end(), isDeviceId(mystring)) == devices.end()) {
Device device;
device.id = mystring;
devices.push_back(device);
std::ofstream temp;
temp.open("temp.txt", std::ios::out | std::ios::app);
temp << mystring << std::endl;
}
return 0;
}
Alternatively, in C++11 and later:
#include <iostream>
#include <string>
#include <fstream>
#include <vector>
#include <algorithm>
struct Device {
std::string id;
std::string foo1;
std::string type;
std::string func;
};
int main() {
std::vector<Device> devices;
std::string mystring;
// fill devices as needed...
mystring = "foo";
if (std::find_if(devices.begin(), devices.end(),
[mystring&](const Device &device) { return (device.id == mystring); }
) == devices.end()) {
devices.emplace_back();
devices.back().id = mystring;
// or, in C++17:
// devices.emplace_back().id = mystring;
std::ofstream temp;
temp.open("temp.txt", std::ios::out | std::ios::app);
temp << mystring << std::endl;
}
return 0;
}