0

I am newbie in C++ programming, I need to write a code to read a particular value from a file. for example if enter input as servername then it has to show ABCDE-1. I am trying with string function I am not able to get the results. Will anyone help in writing the logic.

File data

[ServerName]
ABCDE-1;
[DBLcation]
\\ABCDE-1\dat-520;
[ServerAPPsharename]
LR520APP;
[DerTablePath]
\\ABCDE-1\dat-520\CDM\derd;
[PTPWait]
9995;

In that first part is file data Thank you

to read the file data in string array.

string str;
string Database[10];
if (myfile.is_open()) 
{
int i=0;
while (myfile)
{
getline(myfile, str);
// here I am trying to store each word in  array of string
//Database[i]=str; 
i++;
}
}
else
{
cout << "Error in opening file\n";
}
    

to print the selected option.

cout<<"Enter what you want "<<endl;
cout<<"1.-ServerName \n2.-DBLcation \n3.-ServerAPPsharename \n4.-DerTablePath \n5.-PTPWait"<<endl;

I need write the code to print the value of selected option from file.

KBS
  • 27
  • 5
  • Your `Database` array will have 10 entries in it after you've read in the file. What will entry `0` be? What will entry `1` be? What will entry `2` be? If someone enters `2` for `[DBLocation]` and you display `Database[1]`, will that be showing the right value? – Nathan Pierson Aug 02 '21 at 06:13
  • Don't parse it yourself. There are [windows apis](https://stackoverflow.com/a/12677/4123703) or [boost solution](https://stackoverflow.com/a/23820/4123703) – Louis Go Aug 02 '21 at 06:24
  • 1
    Why don't use a map? 'std::map m { {"ServerName", ""}, {"DBLLcation", ""}, {"ServerAppsharename", ""} };' -> have a look to the answer down... – MiniMik Aug 02 '21 at 07:05
  • @MiniMik I am not able to see the full comment – KBS Aug 02 '21 at 15:53

2 Answers2

1

We can see that your source data follows a certain pattern.

There is a "key" in brackets [] and a "value" after that, followed by a semicolon ;

If we have such a clear pattern, then we can use simple mechanisms. In "formal language" theory, we call this a "Type-3 grammar" or "Regular grammar" according to the Chomsky hierarchy definitions. Please read here about that.

The good point is: You do not need a parser. You can survive with so called regular expressions in such cases.

And, C++ supports regular expressions with the regex library.

I will use the following regex to match the above described pattern: \[([^\]]+)\]\s+([^; ]+);

If you paste this in a regex-online tool like regex101, then you can test it. The description is:

[([^]]+)]\s+([^; ]+);

\[([^\]]+)\]\s+([^; ]+);

\[ matches the character [ with index 9110 (5B16 or 1338) literally (case sensitive)
1st Capturing Group ([^\]]+)
Match a single character not present in the list below [^\]]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
\] matches the character ] with index 9310 (5D16 or 1358) literally (case sensitive)
\] matches the character ] with index 9310 (5D16 or 1358) literally (case sensitive)
\s
matches any whitespace character (equivalent to [\r\n\t\f\v ])
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
2nd Capturing Group ([^; ]+)
Match a single character not present in the list below [^; ]
+ matches the previous token between one and unlimited times, as many times as possible, giving back as needed (greedy)
; 
matches a single character in the list ; (case sensitive)
; matches the character ; with index 5910 (3B16 or 738) literally (case sensitive)

Next:

We will use a std::map to store the data. We can use its map-operator, to store and to access values for keys.

If you want to store a new value, then you can use for example config["ServerAPPsharename"] = "LR520APP". And, if you want to access a value via a key, then you could write std::cout << config["ServerAPPsharename"];

We can simply iterate over all matches (as long as there are any) and store the data in the std::map. We will use regex_search for that.

Then we can easily access all data.

Please see the below code as one of many many possible solutions.

#include <iostream>
#include <fstream>
#include <string>
#include <regex>
#include <map>
#include <iomanip>

std::regex re{R"(\[([^\]]+)\]\s+([^; ]+);)"};

const std::string configFileName{ "test.txt" };

int main() {
    // Open the source file with config data and check, if it could be opened successfully
    if (std::ifstream configFileStream{ configFileName }; configFileStream) {

        // Load the complete content of the file in this string
        std::string configData(std::istreambuf_iterator<char>(configFileStream), {});

        // We will use an associative container to store the key and its value. 
        std::map<std::string, std::string> config{};

        // Now iterate over all pattern matches and store the data in our map
        for (std::smatch sm; std::regex_search(configData, sm, re); configData = sm.suffix())
            config[sm[1]] = sm[2];

        // Example: show value for ServerAPPsharename
        std::cout << "ServerAPPsharename: " << config["ServerAPPsharename"] << "\n\n";

        // show all config data
        std::cout << "\nAll data:\n\n";
        for (const auto& [key, value] : config) std::cout << std::setw(20) << key << ":  " << value << '\n';
    }
    else { // Error, could not open source file. Show message
        std::cerr << "\nError: Could not open '" << configFileName << "'\n\n";
    }
    return 0;
}
A M
  • 14,694
  • 5
  • 19
  • 44
0
#include "stdafx.h"
#include<iostream>
#include<fstream>
#include<string>
using namespace std;
 
void read_file();


int main()
{
    read_file();
    return 0;
}
void read_file()
{
    ifstream myfile;
    myfile.open("config.txt");
    string str;
    if (myfile.is_open())
    {
        cout << "Enter the name :" << endl;
        string in_val;
        cin >> in_val;
        while (getline(myfile, str))
        {           
            if (str == "[" + in_val + "]")
            {
                getline(myfile, str);
                cout << str << endl;
            }
            
        }
     }
    else
        cout << "Error in opening file\n";
}
KBS
  • 27
  • 5