I was right. They have to be null-terminated. I couldn't use memcpy() because that means calling string.h and thus overloading what the program thinks memcpy() is. My question is now this: would the algorithmic complexity be the same either way?

Oh, and I will now extend this program to replace the '+' in ALL files to ' ' (to undo the changes the internet/machine's downloader does to the file)

Let me ask the question this way. Suppose you were going to use the windows.h file to accomplish the goal of locating and modifying all the .docx files that have a '+' in them. Would the algorithmic complexity FOR ANY CASE be more than the number of files in the target directory?

If you're curious I could try to explain your mistake, for now if you want to test if a file is open then you could ask that myfile.is_open()

12

//This is where we rename the files. However, both arguments MUST be character arrays!char * oldfilename = (char*)filename.c_str();

sigh, this is the prototypeint rename(constchar *oldpath, constchar *newpath);
as you can see, it asks for constant strings, and that's precisely what std::string::c_str() returns.
So you ought to write rename( old_name.c_str(), new_name.c_str() );

delete[] oldfilename; ¿why are you doing that? ¿where did you use new[] to allocate that memory?

I was going to one-up this by making this work iteratively on EVERY .docx containing a '+' in the filename, that happens to be in the same directory as this program. The only problem(s) are:
1.) I have no idea as to what is going on with windows.h functions (I might after I finish this systems programming class...)
2.) The algorithmic complexity might be TOO DAMN HIGH!! I hope that it won't be bigger than the number of files in the directory.

Thanks, Andy! I have it, but it only works on the folder it's in (which is typical of C++ programs). Is there a way to make it work on ALL .docx files that are in ALL the subfolders (say, if I have this program in C:\Users I want it to effectively work on ALL .docx files the user would interact with on the C: drive.
Here's my code so far (which works, btw):

#include <iostream>#include <cstring>#include <string>#include <vector>#include <windows.h>#include <stdio.h>usingnamespace std;
void PressEnterToContinue()
{
int c;
printf( "Press ENTER to continue... " );
fflush( stdout );
do
c = getchar();
while ((c != '\n') && (c != EOF));
} //end PressEnterToContinueint main()
{
//This program works by usage of a do-while loop. Before that, it will use a conditional based on the value of the FindFirstFile(filename,FindFileData)//It is worth noting that the second item is a pointer to the WIN32_FIND_DATA structure that returns information about files being searched.//That function should NOT return INVALID_HANDLE_VALUE. If it doesn't, proceed to the loop, which loops until there are no more files found of the//target type.//Remember that the function should be the value of something called a handle.
vector <string> files, oldfiles; //Declare a vector to store the filenames
cout<<"Vector size before the file search operation:"<< files.size()<<endl; //writing test line...
WIN32_FIND_DATA fd;
HANDLE h = FindFirstFile("*.docx", &fd);
if (h != INVALID_HANDLE_VALUE)
{
do
{
files.push_back(fd.cFileName); //write found file to vector...
} //end dowhile (FindNextFile(h, &fd)); //...while there are more files of the desired type to find.
FindClose(h); //Close the handle when you are done.
} //end ifelse
{
cout<<GetLastError()<<endl;
} //end else
cout<<"Amount of files found: "<<files.size()<<endl;
//cout<<"Handle == "<<h;for (int x=0; x<files.size(); x++) //for every file in the vector
{
oldfiles.push_back(files.at(x));
for (size_t s = (files.at(x)).find_first_of('+'); s!=(files.at(x)).npos ;s = (files.at(x)).find('+', s+1))
//locate every '+' in the vector entries....
{
(files.at(x)).at(s) = ' '; //...and replace it with a ' '!
} //end inner for
rename((oldfiles.at(x)).c_str(), (files.at(x)).c_str()); //try the rename just right after the xth new name is being generated...
} //end outer for
PressEnterToContinue();
return 0;
} //end main

PS: I am hoping to sell this (or give this) to my school's Writing Center. They would LOVE this (some of their tutors showed interest...)

#1 To handle subfolders, you need to factor your search routine out of main so it's a function that's passed the starting path, etc. You then call it recursively when the dwFileAttributes member of the WIN32_FIND_DATA struct tells you it's a directory (i.e. has the FILE_ATTRIBUTE_DIRECTORY bit set)

#2 argc + argv are the command line arguments: argc is the count, argv an array of char* pointers to the values.

I know that in the Command Prompt, you have something like dir /b /s "c:\*+*.docx", but the problem is that using a command line argument in a C++ program is, as far as I know, dangerous. (The only two ways I have heard of doing such are system() (EVIL!!) and _exec(). I remember being warned that _exec() could also allow for malevolent system manipulation, so I shied away from that. In fact, I was told that using FindFirstFile(), FindNextFile() was the best way to go. The only problem with this approach is the fact that I can't seem to use my command line syntax. How would I go about this?? (I can't even find the right manual, so how can I read it...)

rename() is a more direct way. See the other parts of this conversation above. However, the problem is in finding the files on the client's computer and removing the '+' and the other space-substitute strings from the filenames (for user-friendliness).

Oh, and I think I might have answered my own question: the FindFirstFile has to know EXACT DIRECTORIES with the file in them. So, to do what this client is asking for, I would have to manually search ALL the folders that would have the .docx files in them. There is some good news:
1.) I might only have to search the Desktop, My Documents, and Downloads (My Documents == Documents)
2.) You can specify to return only the .docx files that have a string in them like this C:/Users/yourfolder/subfolder/*string*.docx

In conclusion, my hopes of calling something similar to the command-line argument are crushed in the sense that I would have to REALLY know what I am looking for. It also seems that my dreams of doing this and keeping the algorithmic complexity to O(kn), where k:=max((files[j]).size()),j∈Z∩[1,n], and n:=number of files found (that meet our search criteria!!), are just that, dreams :( I posted this, instead of deleting my other comment so anyone else with the same hopes can receive the Red Pill here...