如果第二个参数完全包含在第一个参数中,它应该打印为true,但它打印为false

时间:2018-05-28 22:49:18

标签: c

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv){
  char *str1, *str2;
  int str1len, str2len; 
  str1 = argv[1]; str2 = argv[2];
  str1len=strlen(str1);
  str2len=strlen(str2);

  if (str2len>str1len){
    printf("false\n");
    return 0;
  }
  char sub1[100];
  for (int i=0;i<str1len-str2len;i++){
    strncpy(sub1,str1+i,str2len);
    if (strcmp(sub1,str2)==0){
      printf("true\n");
    }
    printf("false\n");
    return 0;
  }
}

我不知道它不起作用的部分是错的。 这是一个问题:一个程序,它接受两个文本字符串作为参数,如果第二个字符串完全包含在第一个字符串中,则打印“true”,后跟换行符,否则返回“false”,然后是换行符。

4 个答案:

答案 0 :(得分:1)

如果str1len&gt; = str2len,当您执行strncpy(sub1, str1+i, str2len)时,它不会复制空终端字符。最后添加一个。

strncpy(sub1, str1+i, str2len);
sub1[str2len] = '\0';

此外,索引是一个接一个。如果您的str2恰好位于str1的末尾,则str1len-str2len不会抓住该str1len-str2len+1 。相反它应该是

char sub1[100];
for (int i=0; i < str1len-str2len+1; i++){
    strncpy(sub1, str1+i, str2len);
    sub1[str2len] = '\0';
    if (strcmp(sub1,str2) == 0){
        printf("true\n");
        return 0;
    }
}
printf("false\n");
return 0;

完成的代码为:

npm install

答案 1 :(得分:1)

一些问题,你没有添加0个字符,你的循环太短了。修复示例:

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv){
  char *str1, *str2;
  int str1len, str2len;
  str1 = argv[1]; str2 = argv[2];
  str1len=strlen(str1);
  str2len=strlen(str2);

  if (str2len>str1len){
    printf("false\n");
    return 0;
  }
  char sub1[100];

  int i = 0;
  for (;i < (str1len-str2len) + 1; i++){
    strncpy(sub1, str1+i, str2len);
    sub1[str2len] = '\0';

    if (strcmp(sub1,str2)==0){
      printf("true\n");
      return 0;
    }
  }
  printf("false\n");
  return 0;
}

答案 2 :(得分:1)

使用打印来帮助调试代码 - 或使用调试器进行类似的打印。这是我提出的代码。

#include <stdio.h>
#include <string.h>

int main(int argc, char **argv)
{
    if (argc != 3)
    {
        fprintf(stderr, "Usage: %s 'haystack string' 'needle'\n", argv[0]);
        return 1;
    }
    char *str1, *str2;
    int str1len, str2len;
    str1 = argv[1];
    str2 = argv[2];
    str1len = strlen(str1);
    str2len = strlen(str2);
    printf("str1 (%d): [%s]\n", str1len, str1);
    printf("str2 (%d): [%s]\n", str2len, str2);

    printf("strstr() says '%s'\n", (strstr(str1, str2) == 0) ? "false" : "true");

    if (str2len > str1len)
    {
        printf("false\n");
        return 0;
    }
    char sub1[100];
    if ((size_t)str2len >= sizeof(sub1))
    {
        fprintf(stderr, "Oops: the needle is too big (%d > %zu)\n", str2len, sizeof(sub1));
        return 1;
    }
    memset(sub1, 'X', sizeof(sub1)-1);
    sub1[sizeof(sub1)-1] = '\0';        // Demonstrated problem with lack of null terminator
    for (int i = 0; i <= str1len - str2len; i++)
    {
        strncpy(sub1, str1 + i, str2len);
        sub1[str2len] = '\0';           // Null terminator that prevents some problems!
        printf("Compare [%s] with [%s]\n", sub1, str2);
        if (strcmp(sub1, str2) == 0)
        {
            printf("true\n");
            return 0;
        }
    }
    printf("false\n");
    return 0;
}

subs61.c编译到subs61并运行时,我会得到,例如:

$ gcc -m64 -g -O3 -std=c11 -pedantic -Wall -Wextra -Werror -Wshadow \
>     -Wmissing-prototypes -Wpointer-arith  -Wold-style-definition \
>     -Wcast-qual -Wstrict-prototypes subs61.c -o subs61
$ subs61 'I am the Walrus' 'I am the Walrus'
str1 (15): [I am the Walrus]
str2 (15): [I am the Walrus]
strstr() says 'true'
Compare [I am the Walrus] with [I am the Walrus]
true
$ subs61 'He said, "I am the Walrus", but did you believe him?' 'I am the Walrus'
'subs61' is up to date.
str1 (52): [He said, "I am the Walrus", but did you believe him?]
str2 (15): [I am the Walrus]
strstr() says 'true'
Compare [He said, "I am ] with [I am the Walrus]
Compare [e said, "I am t] with [I am the Walrus]
Compare [ said, "I am th] with [I am the Walrus]
Compare [said, "I am the] with [I am the Walrus]
Compare [aid, "I am the ] with [I am the Walrus]
Compare [id, "I am the W] with [I am the Walrus]
Compare [d, "I am the Wa] with [I am the Walrus]
Compare [, "I am the Wal] with [I am the Walrus]
Compare [ "I am the Walr] with [I am the Walrus]
Compare ["I am the Walru] with [I am the Walrus]
Compare [I am the Walrus] with [I am the Walrus]
true
$

(嗯:我把它放在与我通常处理Stack Overflow问题不同的目录中,makefile中的编译选项比我通常显示的更严格。)

请注意,复制“比较”代码所做的工作比严格必要的要多得多; strstr()解决方案更加明智。您可以重做循环以避免复制并使用strncmp() - 这类似于strstr()所做的。

    printf("Using strncmp():\n");
    int spotted = 0;
    for (int i = 0; i <= str1len - str2len; i++)
    {
        printf("Compare [%.*s] with [%s]\n", str2len, str1+i, str2);
        if (strncmp(str1+i, str2, str2len) == 0)
        {
            printf("true\n");
            spotted = 1;
            break;
        }
    }
    if (!spotted)
        printf("false\n");

应该将代码打包到从主程序调用的函数(或多个函数)中,这将简化代码的某些方面。例如,不需要spotted变量。这些功能可能无法打印truefalse;他们会返回一个值,调用代码将负责打印。

答案 3 :(得分:0)

您可以使用C string.h函数strstr()来实现您想要的功能。它会搜索“针头”。大海捞针&#39; string,strstr(haystack,needle)。它返回一个指向大海捞针的起始位置的指针。如果它找不到针,则返回空指针。你可以通过测试基本上达到你想要的效果,

if(strstr(argv[1],argv[2]) == NULL){
  printf("false\n");
} else {
  printf("true\n");
}

我认为代码中的问题是printf("false\n"); return 0;过早地退出了您的功能。您没有测试str2的所有可能的起始位置。试试这个,

for (int i=0;i<str1len-str2len;i++){
  strncpy(sub1,str1+i,str2len);
  if(strcmp(sub1,str2) == 0){
    printf("true\n");
    return 0;
  } 
}
printf("false\n");
return 0;

现在,在测试str2的每个起始位置后,您只能进入prinf("false\n");语句。