strstr() 方法在应该返回 null 时提供指针

问题描述 投票:0回答:0

我在尝试使用 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

c pointers reverse strstr
© www.soinside.com 2019 - 2024. All rights reserved.