Reputation: 11
I have to change the "." parts of the IP address to "[.]" using C++. For example: "1.1.1.1" should be converted to "1[.]1[.]1[.]1".
I tried to solve it using normal for-loop,
string defangIPaddr(string address) {
for(int i=0;i<address.size();i++)
{
if(address[i]==".")
{
address[i]="[.]";
}
}
return address;
}
But it throws an error:
Line 6: Char 16: error: no matching function for call to 'strcmp'
6 | if(strcmp(address[i],"."))
| ^~~~~~
/usr/include/string.h:156:12: note: candidate function not viable: no known conversion from 'value_type' (aka 'char') to 'const char *' for 1st argument; take the address of the argument with &
147 | extern int strcmp (const char *__s1, const char *__s2)
| ^~~~~~~~~~~~~~~~~
Can someone please explain what mistake(s) have I made here?
Upvotes: -3
Views: 86
Reputation: 35454
The errors are that
address[i]
to a string "."
address[i]="[.]"
.Even if you fix those errors so that your code compiles cleanly, your loop is very awkward in that you are increasing the size of the original string if .
is found, and at the same time you're looping depending on the size of the string.
Instead of all of this, simply build a new string from the original string by looping over the original string and checking each character to see if it is '.'
:
#include <string>
#include <iostream>
std::string defangIPaddr(std::string address)
{
std::string newString;
for(auto ch : address)
{
if (ch == '.')
newString += "[.]";
else
newString += ch;
}
return newString;
}
int main()
{
std::cout << defangIPaddr("1.1.1.1");
}
Output:
1[.]1[.]1[.]1
Upvotes: 1
Reputation: 10083
I upvoted Paul McKenzie’s answer, but you can also accomplish this with regular expressions:
#include <iostream>
#include <regex>
#include <string>
int main()
{
std::string ip = "192.168.1.1";
std::cout
<< ip
<< " --> "
<< regex_replace( ip, std::regex{ "\\." }, "[.]" )
<< "\n";
}
Upvotes: 0
Reputation: 13076
I would use a reusable function to split up a string into substrings (tokenize like function). And then use std::format to creat the output string. Like this
#include <cassert>
#include <format>
#include <iostream>
#include <string_view>
#include <vector>
auto split_string(std::string_view string, std::string_view delimiters)
{
std::vector<std::string_view> substrings;
if ((string.size() == 0ul))
{
return substrings;
}
if (delimiters.size() == 0ul)
{
substrings.emplace_back(string);
return substrings;
}
auto start_pos = string.find_first_not_of(delimiters);
auto end_pos = start_pos;
auto max_length = string.length();
while (start_pos < max_length)
{
end_pos = std::min(max_length, string.find_first_of(delimiters, start_pos));
if (end_pos != start_pos)
{
substrings.emplace_back(&string[start_pos], end_pos - start_pos);
start_pos = string.find_first_not_of(delimiters, end_pos);
}
}
return substrings;
}
std::string defangIPaddr(const std::string_view sv)
{
auto result = split_string(sv, ".");
assert(result.size() == 4ul);
return std::format("{}[.]{}[.]{}[.]{}", result[0], result[1], result[2], result[3]);
}
int main()
{
std::string_view test{ "192.168.0.1" };
std::cout << defangIPaddr(test);
}
Upvotes: 0