I am trying to declare an Array in .header file and trying to assign values to an Array in .cpp file. But its not working.
I am trying to do is:
ABC.h #include <iostream.h>
class headerFile {
public:
static const char name [];
};
ABC.cpp
#include “ABC.h”
void ABC()
{
const char headerFile::name[];
char *nameList[20];
TSystemFile file;
int count = 0;
TIter next(files);
while ( (file = (TSystemFile)next()) ) {
fname = file->GetName();
nameList[0] = fname;
while (nameList[count] != NULL)
{
nameList[count] = fname;
count++;
headerFile::name[count] = nameList[count]; //Basically I want to store nameList in an name Array which I am defining in .header file.
}
for (int j=0;j<count;j++)
{
printf ("—%s\n", headerFile::name[j]);
}
}
}
You have created an array of const chars (and array of e.g. ‘a’, ‘b’, …) and want to store C strings of type const char* (e.g. “some_name”) in its components. That doesn’t work since the array elements can only hold single characters, not strings.
You should really use the C++ string class which is much simpler to use. Also, instead of using a fixed-size array you should use a vector which can grow to the needed size. Otherwise you might try to write entries beyond the end of the array. It also makes extra (boring) bookkeeping necessary.
void ABC()
{
std::vectorstd::string headerFile::name;
TSystemFile file;
TIter next(files);
while ( (file = (TSystemFile)next()) ) {
// Append the current file’s name to the static list of names.
// file->GetName() returns a const char* which is used to construct a
// std::string with std::string(const char*).
headerFile::name.push_back(file->GetName());
// iterate over list, size is known at runtime
for (unsigned i=0; i<headerFile::name.size(); i++) {
printf ("---%s\n", headerFile::name[i]);
}
TString pwd(gSystem->pwd()); //Get a current directory
TSystemDirectory dir(dirname, dirname); //TSystemDirectory dir(directoy name, Path);
TList *files = dir.GetListOfFiles(); //Displays a list of all files
gSystem->cd(pwd.Data());
if (files) {
TSystemFile *file; //TSystemFile class is internally used by the TBrowser to represent files.
TString fname;
TIter next(files);
A little more info than doesn’t work would be helpful, my crystal ball is broken.
But the code is at least valid C++ (after changing the char* to const char*). Are you sure dir.GetListOfFiles() returns something? The constructor arguments you give it look funny, but I have no experience using it, much less so under Windows. Running the macro in the interpreter should at least give you a line number so you know where to look for errors.
EDIT
OK, our edits crossed. Wrt removing static and it working, I have to say I have no idea what you are trying to do anymore.
TString pwd(gSystem->pwd()); //Get a current directory
TSystemDirectory dir(dirname, dirname); //TSystemDirectory dir(directoy name, Path);
TList *files = dir.GetListOfFiles(); //Displays a list of all files
gSystem->cd(pwd.Data()); // bug fix for ROOT prior to 5.34
if (files) {
TSystemFile *file; //TSystemFile class is internally used by the TBrowser to represent files.
TString fname;
TIter next(files);
while ( (file = (TSystemFile*)next()) ) { //Iterating over a loop
fname = file->GetName();
if ( !(file->IsDirectory()) &&
(!prefix || !(*prefix) || fname.BeginsWith(prefix)) &&
(!suffix || !(*suffix) || fname.EndsWith(suffix)) ) {
std::cout << fname << std::endl;
headerFile::fileName.push_back(fname.Data());
}
} // while ...
} // if (files) …
delete files; // no longer needed
for (unsigned i = 0; i < headerFile::fileName.size(); i++) {
printf ("— %s\n", headerFile::fileName[i].c_str());
} // for …
} // ABC …[/code]
Using vectors a string is getting store in the form of Stack. But if I want to use concatination function of strings then its not working. Because, every time when it reads valu from a stack its appending a particular string.
TString pwd(gSystem->pwd()); //Get a current directory
TSystemDirectory dir(dirname, dirname); //TSystemDirectory dir(directoy name, Path);
TList *files = dir.GetListOfFiles(); //Displays a list of all files
gSystem->cd(pwd.Data());
if (files) {
TSystemFile *file; //TSystemFile class is internally used by the TBrowser to represent files.
TString fname;
TIter next(files);
Int_t count = 0;
while ( (file = (TSystemFile*)next()) ) { //Iterating over a loop
fname = file->GetName();
if ( !(file->IsDirectory()) &&
(!prefix || !(*prefix) || fname.BeginsWith(prefix)) &&
(!suffix || !(*suffix) || fname.EndsWith(suffix)) ) {
cout << fname.Data() << endl;
hf.fileName.push_back(file->GetName());
for (unsigned i=0; i<hf.fileName.size(); i++) {
printf ("---%s\n", hf.fileName[i].c_str());
// This will list all the files which are starting with a prefix = "abc_def";
// abc_def_456.data
// abc_def_123.data
//Comparison works
/* if(strcmp(namefile,hf.fileName[i].c_str()) == 0) //If match with abc_def_123.data found then //ONLY do append operation for only 1 time. But its appending as many times as "hf.fileName.size()" if //match is found.
{
printf("\nMatch found for a file = %s\n",hf.fileName[i].c_str());
strcat(dirname, "/");
strcat(dirname,hf.fileName[i].c_str());
printf("FULL PATH = %s\n",dirname); //BUT here we are getting C:/testFile/abc_def_123.data/abc_def_123.data
fp = fopen(dirname, "r"); // To open a file using we need a exact PATH e.g: C:/testFile /abc_def_123.data
} */
}
}
}
}
}
Is anything wrong in code? Or Have some way to De-Concatenate a string?
Please guide.
you do realize that you are appending to the same dirname variable in the loop? If you want to create a unique dirname for each file you need to use a fresh dirname for each loop iteration, e.g. by moving the dirname declaration inside the loop.
Since ROOT has decent support for C++ I would suggest you to stay away from C-strings (const char*) and use std::strings instead (or TString if that make you feel better). That could make your code simpler and help you avoid issues like that in the first place.
What I am trying to do is … When a respective match for a fileName is found, I want to append a dirName to it. And The repective full path then used by fp to Open that file from that path. I don’t want to append dirName to all the files in the vector list.
What I am trying to do is … When a respective match for a fileName is found, I want to append a dirName to it. And The repective full path then used by fp to Open that file from that path. I don’t want to append dirName to all the files in the vector list.[/quote]
Just as a recommendation …
If you like C-strings so much, you’d better read any book about C-programming language, about memory management, about pointers, about string literals, about C-strings and how they must be programmed in C.
But I would recommend you (as it was already done here) to use either std::string, or TString.
Otherwise - you make the same mistakes again and again in every post and you seem to ignore advices, for example, in your latest code excerpt you have …
I’d say, this is the typical example why you should not use C-strings, if you do not understand them (sure, another problem is that CINT does not see an error here).
[quote=“tpochep”]If you like C-strings so much, you’d better read any book about C-programming language, about memory management, about pointers, about string literals, about C-strings and how they must be programmed in C.
But I would recommend you (as it was already done here) to use either std::string, or TString.[/quote] Actually, the [url=https://root-forum.cern.ch/t/open-files-in-a-directory-with-a-for-loop/12471/17 link[/url] that I gave in my previous post here (to [url=https://root-forum.cern.ch/t/open-files-in-a-directory-with-a-for-loop/12471/17 post of mine[/url] in another topic on this forum) contains a “selection” of several references to materials which deal exactly with these problems.
Well, note that I gave [url=https://root-forum.cern.ch/t/open-files-in-a-directory-with-a-for-loop/12471/17 web link[/url] RIGHT AFTER I saw this particularly hair-raising piece of source code (I mean the same that you mention, too).