string issue

I am trying to solve below issue.

For example, given K = "Test" and string J as follows:

"Jowal Dawn; Pumkin Prejwh; Roger Kim; Joseph Delar; Ivan Shawn; Jimmy Davis; Presilla Mathew'

the below function should return:

string solve(string &J, string &K);

"Jowal Dawn <jowal.dawn@test.com>; Pumkin Prejwh <pumkin.prejwh@test.com>;
Roger Kim <roger.kim@test.com>; Joseph Delar <joseph.delar@test.com>; Ivan Shawn <iavn.shawn@test.com>; Jimmy Davis <jimmy.davis@test.com>; Presilla Mathew<presilla.mathew@test.com>"


Assume that: N is an integer within range[3..1,000];
M is an integer within range[1..100];
string J consists only of letters (a-z and/or A-Z), spaces, hyphens and semicolons
string J contains valid names; no name appears more than once.
string K consists only of letters(a-z and/or A-Z)



Below is what I have tried to validate emailaddrs for those user names.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<iostream>
#include<regex>
#include<stdio.h>
using namespace std;

bool VerifyEmail(string email)
{
     //here \w assumed as "word character", usually [A-Za-z0-9_].
 		const regex patterntypes("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
    return regex_match(email,patterntypes);
}
int main()
{
    string strg;
    cout<<"Enter your EmailAddrs:"<<endl;
    cin>>strg;
    if(VerifyEmail(strg))
        cout<<"Your EmailAddrs is valid"<<endl;
    else
        cout<<"Your EmailAddrs is invalid"<<endl;
    return 0;
}
Last edited on
Hello. Respectfully I don't understand clearly what you are trying to do. The explanation about K,J, N and all everything data are confusing for me. At the address below you have an interesting way to check a string. You have done a similar code including an input. Maybe you should to lower input entry before check it as a string - and if you have an array (or a vector) you could loop the isValid request ++

https://www.geeksforgeeks.org/check-if-given-email-address-is-valid-or-not-in-cpp/

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <iostream>
#include <regex>

bool isValid(const std::string& email)
{   // regular expression
    const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");
    return regex_match(email, pattern);
}

int main()
{
    std::cout << "enter a mail address :" << std::endl;
    std::string email;

    do {
        std::cin >> email;

        std::transform(email.begin(), email.end(), email.begin(),
            [](unsigned char c) { return std::tolower(c); });
        
        isValid(email) ? std::cout << email << " : " << "valid email" << std::endl
                       : std::cout << email << " : " << "invalid email" << std::endl;
    } while (email != "exit");
}


Are you trying to find an address eMail according to a name?
Is there a file to read?
Last edited on
I am trying to write this function string solve(string &J, string &K);
based on the above inputs. This function is expected to return Jowal Dawn <jowal.dawn@test.com> and other user names which are valid as well as email addrs. There is no file to read.
Last edited on
This is a homework assignment. OP wrote “Example” when he should have written “Test”.

The point is to transform each element of the J string to an email address.

Hence, “Jowal Dawn” ⟶ “Jowal Dawn <jowal.dawn@test.com>”.


There is no need to validate anything. You need to implement the function solve, which breaks the string into individual names, transforms those names into email addresses, and builds a new string with those parts.
(IRL, it is only possible to validate an email address by getting a response from someone you emailed.)


Don’t try to do everything with the regular expression. Only use it to get the pieces. C++ has a regex_iterator which will allow you to handle each name in J one at a time. All you need is a loop:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
std::string solve( std::string & J, std::string & K )
{
  std::string result;

  std::regex re( ... ); // this is where you need to think

  auto first = std::regex_iterator( J.begin(), J.end(), re );
  auto last  = std::regex_iterator();

  for (auto iter = first;  iter != last;  ++iter)
  {
    std::smatch match = *iter;

    // Use the pieces of `match` to build your new piece of string:
    auto first_name = ...;
    auto last_name = ...;

    if (!result.empty()) result += "; ";

    result += first_name + " " + last_name 
      + " <" + lowercase(first_name) + "." + lowercase(last_name)
      + "@" + lowercase(K) + ".com>";
  }

  return result;
}

Notice that you will need a little utility function (lowercase()) to convert a string to lowercase.

The tricky part is designing your regular expression. Remember: you can get sub-expressions by using parentheses in the regular expression. The match variable can be treated like an array to access those sub-matches.

    match[0] is the entire matched expression
    match[1] is the first parenthesized sub-expression matched
    ... and so on


Also remember that you can tag something as optional with a question mark.

    one;? — the ; is optional.


Finally, remember that the regular expression matches the input string. It does not match (or create) the result string.

Good luck!
Thanks for your help. It is a little bit more understandable now. I don't understand why the function string solve(string &J, string &K) must take two parameters? One for the first name - one for the last name? If I understand correctly, simply we are talking about concatenation here?

1
2
3
result += first_name + " " + last_name 
      + " <" + lowercase(first_name) + "." + lowercase(last_name)
      + "@" + lowercase(K) + ".com>";
Last edited on
This is not an assignment, rather I made a type mistake in the description, so had corrected it. Anyhow, do you mean to create some util function this way?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <string>
#include <cctype>
#include <iostream>
#include <algorithm>

//Util fn
char lowercase(unsigned char ch){

   if (std::isupper(ch)) 
      return std::tolower(ch);
   else if (std::islower(ch)) 
      return std::toupper(ch);
   else
      return ch;
}

int main(){
  std::string str = "jUmpjumP007";
  std::string output;
  output.resize(str.length());
  
  std::transform(str.begin(), str.end(), output.begin(), lowercase);
  std::cout << output; 
}
Last edited on
solve( "Clark Kent; Lois Lane", "Example" )
  ⟶ "Clark Kent <clark.kent@example.com>; Lois Lane <lois.lane@example.com>"

solve( "Clark Kent; Lois Lane", "DailyPlanet" )
  ⟶ "Clark Kent <clark.kent@dailyplanet.com>; Lois Lane <lois.lane@dailyplanet.com>"
Without using regex, then consider (as C++20):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#include <string>
#include <ranges>
#include <iostream>
#include <cctype>
#include <string_view>
#include <vector>

namespace rngs = std::ranges;

std::vector<std::string> split(const std::string& line, char del) {
	std::vector<std::string> s;

	for (const auto& word : rngs::split_view(line, del)) {
		std::string_view n { word.begin(), word.end() };

		while (n.starts_with(' '))
			n.remove_prefix(1);

		while (n.ends_with(' '))
			n.remove_suffix(1);

		if (!n.empty())
			s.emplace_back(n.begin(), n.end());
	}

	return s;
}

std::string tolower(std::string s) {
	for (auto& ch : s)
		ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));

	return s;
}

std::string solve(const std::string& names, const std::string& email) {
	const auto lcemail { tolower(email) };
	const auto vn { split(names, ';')};

	std::string emails;

	for (const auto& n : vn) {
		const auto na { split(n, ' ') };

		if (!emails.empty())
			emails += "; ";

		emails += na.front() + ' ' + na.back() + " <" + tolower(na.front()) + '.' + tolower(na.back()) + '@' + lcemail + ".com>";
	}

	return emails;
}

int main() {
	std::cout << solve("  Clark Kent; Lois Lane ; ", "Example") << '\n';
	std::cout << solve("Clark Kent; Lois Lane", "DailyPlanet") << '\n';
}


which displays:


Clark Kent <clark.kent@example.com>; Lois Lane <lois.lane@example.com>
Clark Kent <clark.kent@dailyplanet.com>; Lois Lane <lois.lane@dailyplanet.com>

Last edited on
Or using regex, there are some interesting alternatives...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#include <regex>
#include <iostream>

std::string toLower(std::string s)
{
    for (auto& c : s)
        c = tolower(c);

    return s;
}

void solve(std::string s, std::string e)
{
    std::regex regx("[\\; ]");
    std::sregex_token_iterator first{ s.begin(), s.end(), regx, -1 }, last;
    std::vector<std::string> data{ first, last };

    for (int i = 0; i < data.size() - 1; ++i)
    {
        if (i % 2) continue; // little trick
        std::cout << data[i] << " " << data[i + 1] << "\t";
        std::cout << "<" << toLower(data[i]) << "." << toLower(data[i + 1]) << "@" << e << ">" << std::endl;
    }
}

int main() 
{
    std::string input = "Clark Kent;Lois Lane;Lex Luthor";
    solve(input, "dailyplanet.com");
}


Clark Kent	 : <clark.kent@dailyplanet.com>
Lois Lane	 : <lois.lane@dailyplanet.com>
Lex Luthor	 : <lex.luthor@dailyplanet.com>
Last edited on
Heeey... Lex Luthor never worked for the Daily Planet...
But he was one of its owners :)
https://en.wikipedia.org/wiki/Daily_Planet
Last edited on
Heh, well, I admit I’ve never been much of a Superman/Marvel fan since Miller ruined Batman.
Hi seeplus

While I try to run on C++ shell, it throws below errors.
How did you compile?

main.cpp:13:32: error: no member named 'split_view' in namespace 'std::ranges'
for (const auto& word : rngs::split_view(line, del)) {
~~~~~~^
1 error generated.
std::ranges is a relatively new features so it's not fully supported everywhere yet.
Last edited on
While I try to run on C++ shell, it throws below errors.
How did you compile?


With VS2022 17.3
It does not work even using /std:c++20
You have to set your project to /std:c++latest
Last edited on
17.1.6 isn't the latest version - 17.3.4 is. Update it! It then compiles OK as /std:c++20

Topic archived. No new replies allowed.