Also, pointers are not like arrays right? so how can a pointer increment to the "end". |
A "feature" from C that C++ inherited is that arrays decay to pointers.
This means that whenever you use the name of an array, it becomes a pointer to the first element.
1 2 3 4 5 6 7 8 9 10 11 12
|
#include <iostream>
int main()
{
int arr[30];
if (arr == &arr[0])
{
std::clog << "arr is the same as &arr[0],\n";
std::clog << "(which is the memory address of the first element)\n";
}
}
|
Unfortunately because of this "decay" the size information is lost when you pass the array to a function.
So what can you do?
1) Use
std::strlen() inside
p_r() to find out the sizes of
line and
pattern.
2) Change
p_r() to also accept lengths of
line and
pattern.
3) Use C++ strings (
std::string) like any C++ programmer would.
Example C++ code for
1):
1 2 3 4 5 6 7 8 9 10 11 12 13 14
|
#include <cstddef>
#include <cstring>
// ...
// you should use pointers to const char instead of pointers to char,
// because you probably don't intend to change the original line and pattern
int p_r(const char *line, const char *pattern)
{
const std::size_t line_len = std::strlen(line);
const std::size_t pattern_len = std::strlen(pattern);
// ...
}
|
If you're programming in C, the code above uses different header names and the
std:: qualifiers must be removed.
1 2 3 4 5 6 7 8 9 10 11 12
|
#include <stddef.h>
#include <string.h>
// ...
int p_r(const char *line, const char *pattern)
{
const size_t line_len = strlen(line);
const size_t pattern_len = strlen(pattern);
// ...
}
|
Example C code for
2):
1 2 3 4 5 6 7 8
|
#include <stddef.h>
// ...
int p_r(const char *line, size_t line_len, const char *pattern, size_t pattern_len)
{
// ...
}
|
Example C++ code for
3) (this is the "proper" way to do this in C++):
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#include <iostream>
#include <string>
// ...
// pass line and pattern as const references for performance
int p_r(const std::string &line, const std::string &pattern)
{
std::clog << "length of line is: " << line.length() << '\n';
std::clog << "length of pattern is: " << pattern.length() << '\n';
// ...
}
|
If you want to be able to modify
line inside
p_r() and without changes being visible outside
p_r(), simply pass
line by value instead of by
const reference:
1 2 3 4 5 6 7 8 9 10 11 12 13
|
#include <iostream>
#include <string>
// ...
int p_r(std::string line, const std::string &pattern)
{
line = "Hello.";
// in this function we have our own local copy of line, so
// we can freely change its contents to whatever we want
// ...
}
|
The problem is I don't know how to implement the special case %???%. Also, pointers are not like arrays right? |
One approach could be splitting the
line into words (words being separated by whitespace). From the example in your original post this should work fine because there is no punctuation.
Then the
"%word%"
pattern means that the "word" has to match completely.
Remove the percent signs
% then check each words in line, against "word".
Splitting the
line into words can be done easily by using C++ string streams.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
#include <cstddef>
#include <iostream>
#include <sstream>
#include <string>
int main()
{
const std::string line = "Batman defeats the Joker in the end";
std::stringstream words(line);
std::string current_word;
std::size_t count = 0;
while (words >> current_word)
{
std::cout << "Word number " << count << " is: \"" << current_word << "\"\n";
++count;
}
std::cout << std::endl;
}
|
If you're programming in C, then instead of C++ string streams you will use the function
strtok(), described here:
http://www.cplusplus.com/reference/cstring/strtok/
Finally, your task seems to be about implementing a simple regular expressions (regex) library.
Because pattern matching is very useful feature for a programming language to have, C++ already has one
regex library of its own.
http://www.cplusplus.com/reference/regex/