字符串操作(比较两个字符串并复制通用字符串)

时间:2019-06-17 00:03:53

标签: c

我必须使用3个字符串,“干草堆”字符串,“ needle”字符串和缓冲区字符串。我必须在干草堆字符串中搜索与针串匹配的序列,然后将找到的结果(整个子串)从干草堆字符串复制到缓冲区中(不要复制针串)。

然后,如果在干草堆中找到匹配的序列,我必须返回1;如果找不到针,则必须返回0。

这是驱动程序代码:

#include "myprog.h"
#include <assert.h>
#include <limits.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>

int myStrStr(char haystack[], char needle[], char buffer[]);
int main(){

    char haystack[][20] = {"chocolate","vanilla","caramel","strawberry","banana","cherry"};
    char needle[][20] = {"choc","lla","am","strawberry","na","terrible"};
    char buffer[255];

    printf("\n\t=========Testing myStrStr with '%s' and substring '%s'===========\n\n", haystack[0], needle[0]);
    int result = myStrStr(haystack[0],needle[0],buffer);
    assert(result == 1 && strcmp(needle[0], buffer) == 0);
    printf("\n\t\t....Test Passed\n");

    printf("\n\t=========Testing myStrStr with '%s' and substring '%s'===========\n\n", haystack[1], needle[1]);
    result = myStrStr(haystack[1],needle[1],buffer);
    printf("needle: %s, buffer: %s\n", needle[1], buffer );
    assert(result == 1 && strcmp(needle[1], buffer) == 0);
    printf("\n\t\t....Test Passed\n");

    printf("\n\t=========Testing myStrStr with 'blueberry' and substring 'ueber'===========\n\n");
    result = myStrStr(haystack[2],needle[2],buffer);
    assert(result == 1 && strcmp(needle[2], buffer) == 0);
    printf("\n\t\t....Test Passed\n");

    printf("\n\t=========Testing myStrStr with 'strawberry' and substring 'strawberry'===========\n\n");
    result = myStrStr(haystack[3],needle[3],buffer);
    assert(result == 1 && strcmp(needle[3], buffer) == 0);
    printf("\n\t\t....Test Passed\n");

    printf("\n\t=========Testing myStrStr with 'banana' and substring 'na'===========\n\n");
    result = myStrStr(haystack[4],needle[4],buffer);
    assert(result == 1 && strcmp(needle[4], buffer) == 0);
    printf("\n\t\t....Test Passed\n");

    printf("\n\t=========Testing myStrStr with 'grapefruit' and substring 'terrible'===========\n\n");
    result = myStrStr(haystack[5],needle[5],buffer);
    assert(result == 0);
    printf("\n\t\t....Test Passed\n");
}

我必须在.h文件中编写代码。下面是我的.h文件

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

int myStrStr(char  * haystack, char * needle, char * buffer)
{
char *hays,*nee;
hays=haystack;
nee=needle;
buffer[0]='\0';
char s=sizeof(buffer);
char *tempbuffer=(char *)malloc(s);
  if(*hays=='\0' || *nee=='\0' )
  {
  printf("Haystack and Needle Cannot be Compared because Empty string cannot be compared\n");
  return 0;
  }     
  for(;*hays!='\0' ;hays++)
  {
    while(*hays==*nee && *hays!='\0' && *nee!='\0' )
    {        
      *tempbuffer=*hays; 
      strcat(buffer,tempbuffer);
      hays++;
      nee++;
    }
    if(*nee!= '\0'&& *tempbuffer!= '\0')
    {
    nee=needle;
    *buffer=NULL;
    }    
  }
  printf("%s\n",buffer);
  if(*nee=='\0')
  {  return 1;  }
  return 0;
}

尝试执行时收到以下消息:

Assertion failed: result == 1 && strcmp(needle[0], buffer) == 0, file driver.c, line 35

编辑:

我对代码进行了以下更改:

  1. char *tempbuffer=(char *)malloc(s);更改为char tempbuffer[255];

  2. 已删除*buffer=NULL;

现在程序正在部分执行。对于第一个字符串,即“ chocolate”和“ choc”,它会打印所需的公共子字符串。

c
h
o
choc

                ....Test Passed

当必须打印“ vanilla”和“ lla”中的公共子字符串时,问题开始。它仍在打印两个字符串中的通用字母,但它还会打印前一个字符串中的最后一个字母

c
l
l
lla
needle: lla, buffer: lla

                ....Test Passed

如您所见,它会打印“ c”,它是前一个字符串“ choc”的最后一个单词

第三个字符串也一样,即“焦糖”和“上午”,但是我的断言失败了

a
a
a
aam
needle: am, buffer: aam
Assertion failed: result == 1 && strcmp(needle[2], buffer) == 0, file assignment1.c, line 36, function main
Abort

我不明白为什么这个断言失败,为什么前一个字符串的最后一个字母也被复制到下一个字符串?

1 个答案:

答案 0 :(得分:1)

您的代码中充满了禁忌与反常的事物。我将列出其中的一些。

  1. 头文件(.h)不得分配内存。没有变量声明,没有C代码。
  2. assert()通常用于不同目的。在您的代码中,根据您的意图,if()就足够了。
  3. 可以使用for循环使整个驱动程序代码更短,更易读,以解析数组的所有值。
  4. char s=sizeof(buffer);完全不受欢迎。该函数接收指向char而不是数组的指针。因此,无论在驱动程序中使用什么,结果始终为X(X是指针的大小,与体系结构和编译器相关的,而不是数组的大小)。
  5. myStrStr()中,您将非标准forwhile混合使用(难以快速阅读和理解)。由于您从一开始就不知道迭代次数,因此只有while()最合适。
  6. 如果myStrStr()恰好指向未分配的内存,则buffer[0]='\0';中的buffer是问题的根源。
  7. “我必须在.h文件中编写代码。” 是谁强迫您这样做?这是非常糟糕的做法,原因有很多。
  8. 在主文件中,没有包括.h文件。
  9. 您应使用缩进和空白行,以使代码可读易懂。
  10. 由于4,tempbuffer太短/太小,每当在第一个字符之后写入任何字符时,缓冲区就会溢出。
  11. "because Empty string cannot be compared"真的吗?为什么?

实用:尝试解决尽可能多的问题。

  1. 替换 char * tempbuffer =(char *)malloc(s); 与 char tempbuffer [255]; (即buffer的大小)

  2. 我了解您的代码的方式tempbuffer实际上可以是简单的char-没有字符串,没有数组,没有动态分配...

  3. 无需为每个字符执行strcat(buffer,tempbuffer);

  4. *buffer=NULL;覆盖函数buffermain()的内容。

  5. 使用调试器并逐步进行调整。


编辑

此行:

  strcat(buffer,tempbuffer);

是严重问题的根源,因为tempbuffer的内容可能是随机的。您不知道内部是否有任何'\ 0',因此strcat()可能会连接所有RAM-直到达到'\ 0'。一种解决方案是在函数开始时将tempbuffer的所有值都初始化为'\ 0'。