我在尝试使用 strstr() 查找字符串的子字符串时遇到问题。出于某种原因,当我使用
I eat appls
作为 haystack 字符串,以及 apples
作为 needle 子字符串时,它返回一个内存地址,而不是 null.
我不太明白为什么会这样。有人可以解释吗?
//CLA: ./find -p apple
//INPUT: I like different types of fruit, especially apple and orange!
//OUTPUT: I like dif...apple...ange!
//CLA: ./find -p apple
//INPUT: I like different types of fruit, especially apple
//OUTPUT: I like dif...apple
//CLA: ./find -p apple
//INPUT: I like apple
//OUTPUT: I like apple
#include<stdio.h>
#include<string.h>
#include<strings.h>
#include<stdlib.h>
#include <ctype.h>
void swap(char* arr[], int i, int j){
void* temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
char* strcasestr(char *a, char *b){
const char* p1 = a;
const char* p2 = b;
const char* r = *p2 == 0? a:0;
while(*p1 != 0 && &p2 !=0){
if(tolower((unsigned char)*p1)==tolower((unsigned char)*p2)){
if(r==0){
r=p1;
}
p2++;
}
else{
p2 =b;
if(r != 0){
p1 = r + 1;
}
if(tolower((unsigned char)*p1) == tolower((unsigned char)*p2)){
r = p1;
p2++;
}
else{
r = 0;
}
}
p1++;
}
return *p2 ==0 ?(char*)r : 0;
}
char *strstr_fully_matched(char *haystack, char *needle) {//needle = "apple"
char *rv;
char padded_needle[strlen(needle) + 3];
padded_needle[0] = ' ';
strcpy(padded_needle + 1, needle);
padded_needle[strlen(needle) + 1] = ' ';
padded_needle[strlen(needle) + 2] = '\0';//" apple "
if (!strncmp(haystack, padded_needle + 1, strlen(needle) + 1)) {
return haystack; // needle is at the beginning
}
if ((rv = strstr(haystack, padded_needle)) != NULL) {
return rv + 1; // needle is at the middle.
}
padded_needle[strlen(needle) + 1] = '\0';
if ((rv = strstr(haystack, padded_needle)) != NULL &&
rv[strlen(padded_needle)] == '\0') {
return rv + 1; // needle is at the end.
}
return NULL;
}
char *strstr_fully_match_ignore(char *haystack, char *needle) {//needle = "apple"
char *rv;
char padded_needle[strlen(needle) + 3];
padded_needle[0] = ' ';
strcpy(padded_needle + 1, needle);
padded_needle[strlen(needle) + 1] = ' ';
padded_needle[strlen(needle) + 2] = '\0';//" apple "
if (!strncasecmp(haystack, padded_needle + 1, strlen(needle) + 1)) {
return haystack; // needle is at the beginning
}
if ((rv = strcasestr(haystack, padded_needle)) != NULL) {
return rv + 1; // needle is at the middle.
}
padded_needle[strlen(needle) + 1] = '\0';
if ((rv = strcasestr(haystack, padded_needle)) != NULL &&
rv[strlen(padded_needle)] == '\0') {
return rv + 1; // needle is at the end.
}
return NULL;
}
void book_s_qsort(char*v[], int left, int right){
int i, last;
if(left >= right)
return;
swap(v, left, left + (right-left)/2);
last = left;
for(i = left+1; i <= right;i++)
if(strcmp(v[i],v[left]) < 0){
swap(v, ++last, i);
}
swap(v, left, last);
book_s_qsort(v, left, last-1);
book_s_qsort(v, last+1, right);
}
void error(char* message){
printf("%s\n", message);
}
char* lineptr[1000];
char* strstr_updated(char* haystack, char* needle, int match, int ignore){
if(match && !ignore)
return strstr_fully_matched(haystack, needle);
else if(match && ignore){
return strstr_fully_match_ignore(haystack, needle);
}
else if(!match && ignore){
return strcasestr(haystack, needle);
}
else
return strstr(haystack, needle);
}
/*char * reverse_array(char *line[], int num_of_elems){
for (int i = num_of_elems; i >= 0 ; i--){
printf("%d", i);
}
}*/
int main(int argc, char* argv[]) {
int except = 0, number = 0, sort = 0, reverse = 0, match = 0, ignore=0,first=0;
char *e;
int index;
if (argc < 2) {
error("fatal error: too few arguments");
return 1;
}
int i = 1;
while (argc != 2) {
char *current_arg = argv[i++];
if (current_arg[0] != '-') {
error("fatal error: illegal CLAs");
return 2;
}
while (*++current_arg) {
switch (*current_arg) {
case 'x':
case 'X':
except = 1;
break;
case 'n':
case 'N':
number = 1;
break;
case 's':
case 'S':
sort = 1;
break;
case 'r':
case 'R':
reverse = 1;
break;
case 'm':
case 'M':
match = 1;
break;
case 'c':
case 'C':
ignore = 1;
break;
case 'f':
case 'F':
first = 1;
break;
default:
error("fatal error: illegal option entered");
return 3;
}
}
argc--;
}
char *pattern = argv[i];
printf("pattern is %s, n = %d, s = %d, r = %d, m = %d, x = %d\n", pattern, number,
sort, reverse, match, except);
if (reverse && sort) {
error("fatal error: can't use -r and -s in the same execution");
return 4;
}
if (first && except) {
error("fatal error: can't use -f and -x in the same execution");
return 4;
}
//input stream read operation...
char line[1000];
i = 0;
// Reads input from commandline and adds lines to stack
while (fgets(line, 1000, stdin)) {
if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';//drop the new line
lineptr[i++] = strdup(line);//malloc to allocate space in heap and strcpy to copy line to heap
}//i represents the no of sentences input by the user
if (!sort && !reverse) {
int count = i -1;
for (int j = 0; j < i; j++) {
char *result = strstr_updated(lineptr[j], pattern, match,ignore);
char *line_no = (char *) malloc(10);
sprintf(line_no, "%d. ", (j + 1));
//if pattern is found and -x doesn't exist
//or if pattern is missing and -x exists
//then print the line in the output
if ((result && !except) || (!result && except))
printf("%s%s\n", number ? line_no : "", lineptr[j]);
if(first){
e = strstr(lineptr[count],pattern);
index = (int)(e-lineptr[count]);
printf("the first index is %d\n\n",index);
}
count--;
}
} else if (sort) {
int count = i -1;
book_s_qsort(lineptr, 0, i - 1);
for (int j = 0; j < i; j++) {
char *result = strstr_updated(lineptr[j], pattern, match,ignore);
char *line_no = (char *) malloc(10);
sprintf(line_no, "%d. ", (j + 1));
if ((result && !except) || (!result && except))
printf("%s%s\n", number ? line_no : "", lineptr[j]);
if(first){
e = strstr(lineptr[count],pattern);
index = (int)(e-lineptr[count]);
printf("the first index is %d\n\n",index);
}
count--;
}
} else {//reversed
//complete this part as well...
//reverse_array(lineptr,i);
int count = i -1;
for (int j = 0; j < i; j++) {
char *result = strstr_updated(lineptr[j], pattern, match,ignore);
char *line_no = (char *) malloc(10);
sprintf(line_no, "%d. ", (j + 1));
printf("line_no = %p \n", result);
//return the first occurrence of character in string
if ((result && !except) || (!result && except)){
//prints lines in reverse order
printf("%s%s\n", number ? line_no : "", lineptr[count]);
if(first && result){
e = strstr(lineptr[count],pattern);
index = (int)(e-lineptr[count]);
printf("the first index is %d\n\n",index);
}
}
count--;
}
return 0;//no error occured!
}
}
lineptr[]
存储来自命令行的参数。 E