在C编程中使用字符串和子串的基础知识

时间:2014-10-21 23:14:40

标签: c string substring

我一直试图通过阅读教科书来学习C编程,但对字符串和子字符串的工作原理感到困惑。 我知道java中的字符串和子字符串是什么,但无法弄清楚C中的语法。

这里有一本我认为可能很容易的书中的问题,但我无法理解。

编写并测试函数氢氧化物,如果其字符串参数在子字符串OH中结束,则返回1表示为真。

建议用KOH和NaCl测试功能。

另外,如何在字符串末尾删除和添加字母? 就像,如果由于某种原因我想将NaCl改为NaOH?

非常感谢任何帮助和解释。

ETA: 我想我最困惑的是如何让程序查看字符串中的最后两个字母并将它们与OH进行比较。 我也不确定如何将字符串传递给函数。

2 个答案:

答案 0 :(得分:1)

在C中,我们使用以null结尾的字符串。那就是“隐形”,0值。不是ASCII“0”,而是零值,如8位0x00。您可以使用'\ 0'或“\ 0”或不带引号0在文本文本中表示它,但是,在文字字符串中它是多余的,因为大多数函数如strcmp()或strstr()或strcat()都期望和使用null终止字符串。 Null char是C标准字符串函数的停止符号。

使用C库调用实现此操作的一种简单方法是测试子字符串是否存在,然后测试子字符串的长度,以验证它是否在字符串的末尾。

假设buf是一个大字符串缓冲区,char buf[1024]char *temp是一个临时变量。

  1. temp = strstr(buf, "OH")返回指向“OH”的指针,如果存在于任何偏移的buf中。
  2. strlen(temp)获取temp的长度,如果在字符串的末尾,它将是2(不包括null终止符),所以如果原始字符串是“OHIO”或“SOHO”它将不匹配,因为它分别是4和3。
  3. 以上是代码的核心,而不是完整的强大实现。您需要检查有效的返回值等。

    char buf[1024];
    char *temp;
    
    strcpy(buf, "NaOH");
    
    if((temp = strstr(buf, "OH")) != 0)
    {
          // At this point we know temp points to something that starts with "OH"
          // Now see if it is at the end of the string
          if(strlen(temp) == 2)
                return true;          // For C99 include stdbool.h
    
          return false;
    }
    

    你可能会变得模糊,直接检查空终结符,会更快。这段代码是安全的,只要它在strstr()的if()内,否则如果你不知道一个字符串是至少N个字符长,就不要这样做。

          if(temp[2] == '\0')
                return true;          // For C99 include stdbool.h
    

    只要附加到字符串,请阅读strcat上的文档。请记住strcat,你必须在你要追加的缓冲区中有足够的空间。它不像C ++ std :: string或Java / C#字符串,它们会根据需要动态调整大小。在C中,你可以自己完成所有这些。

答案 1 :(得分:1)

字符串是以特殊 null - 终止字符'\0'结尾的字符序列。如果没有\0,则使用字符串的函数将停止,直到找到\0符号。这个字符可能发生在字符串结束后的任何地方(我的意思是没有\0的字符串),然后才停止。

以下示例显示了此以null结尾的字符的必要性:

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

int main()
{
    char string[] = "Hello!";

    printf("original string:\n%s\n\n", string);

    memset(string, '-', 5);
    printf("memset doesn't affect the last two symbols: '!' and '\\0':\n%s", string);

    memset(string, '-', 6);
    printf("\n\nmemset doesn't affect the last symbol: '\\0':\n%s\n\n", string);

    memset(string, '-', 7);
    printf("memset affects all symbols including null-terminated one:\n%s", string);

    return 0;
}

/* OUTPUT:
original string:
Hello!

memset doesn't affect the last two characters: '!' and '\0':
-----!

memset doesn't affect the last character: '\0':
------

memset affects all characters including null-terminated one:
-------@↓@
*/

子串是字符串中的字符序列。它可能小于或等于字符串。 假设"NaOH"是一个字符串。然后子字符串可以是:"N""a""O""H""Na""aO""OH",{{1 },"NaO""aOH"。要查找子字符串是否在字符串中,您可以使用"NaOH"函数。它的原型是strstr

此代码显示此功能的结果:

char * strstr (       char * str1, const char * str2 );

对于第一个printf,它会打印从&#39; h&#39;的位置开始的字符。并且当它到达以空格终止的字符时,它将在&#39; o&#39;之后,它将停止,与之前的程序完全相同。


要使程序更具交互性,您可以声明数组,然后指向它。数组大小必须足以存储最长的公式。假设,100就足够了:

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

int main()
{
    char *ptrCh = NULL;

    ptrCh = strstr("hello", "h");
    printf("ptrCh: %p\n", ptrCh);
    printf("%s\n\n", ptrCh);

    ptrCh = strstr("hello", "z");
    printf("ptrCh: %p\n", ptrCh);
    printf("%s\n\n", ptrCh);

    return 0;
}

/* OUTPUT:
ptrCh: 00403024
hello     

ptrCh: 00000000
(null)
*/

重写字母在字符串的末尾。这是一个小程序。注意评论:

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

int main()
{
    char buf[100] = {0};
    char *ptr = &buf[0];

    scanf("%s", ptr);

    // printf() gets a pointer as argument
    printf("%s\n", ptr);   

    // printf() gets also a pointer as argument. 
    // When you pass arrays name without index to a function,
    // you pass a pointer to array's first element.
    printf("%s", buf);     

    return 0;
}