(九)字符串和字符 -- 4. strlib.h接口

4. strlib.h接口

  • 隐含原型(implicit prototype)
    是一个函数调用实例,包括参数的名字。
    例如,RandomInteger的隐含原型为RandomInteger(low, high)

4.1 确定字符串的长度

  • 字符串的长度(length)
    字符串包含的字符总数(包括所有的字母、数字、空格、标点符号和特殊字符)。

该功能可以通过调用strlib.h接口的StringLength(s)函数实现:

StringLength("Hello, world.\n")

从用户读入一行文本,计算其长度,代码实现如下:

#include <stdio.h>
#include "strlib.h"

main() {
    string s;
    s = malloc(1000); // 分配所需内存空间,并返回一个指向它的指针。
    printf("Input a sentence: ");
    scanf("%[^\n]", &s[0]); // replace "%s" with "%[^\n]" to support blank space
    printf("Length of sentence is: %d\n", StringLength(s));
}

4.2 从一个字符串中选择字符

在C语言中,字符串中的位置是从0开始编号的。

strlib.h接口的IthChar函数支持返回指定下标位置的字符。
例如,IthChar(str, 5)返回下标位置为5的字符,是字符串中的第6个字符。

定义函数LastChar,返回str中的最后一个字符:

#include <stdio.h>
#include "strlib.h"

/* Get the last character in an inputted word. */

/* Function Prototype */
char LastChar(string s);

/* Main Program */
main() {
    string s;
    s = malloc(1000);
    printf("Input a word: ");
    scanf("%s", &s[0]);
    printf("The last char is: %c\n", LastChar(s));
}

/* Function */
char LastChar(string s) {
    return IthChar(s, StringLength(s) - 1);
}

4.3 连接

strlib.h接口的Concat函数支持两个字符串的连接(concatenation)操作。
Concat函数每次只能取两个参数。为了连接三个或更多的字符串,必须多次调用Concat

定义函数ConcatNCopies(s, n),返回一个由n个str拷贝连接的字符串:

#include <stdio.h>
#include "strlib.h"

/* Return a new string composed of n copies of an inputted string. */

/* Function Prototype */
string ConcatNCopies(string s, int n);

/* Main Program */
main() {
    string s;
    int n;
    s = malloc(1000);
    printf("Input a string: ");
    scanf("%s", &s[0]);
    printf("Input a positive integer: ");
    scanf("%d", &n);
    printf("Concat %d copies %s is: %s\n", n, s, ConcatNCopies(s, n));
}

/* Function */
string ConcatNCopies(string s, int n) {
    string result;
    int i;
    result = "";
    for (i = 1; i <= n; i++)
    {
        result = Concat(result, s);
    }
    return result;
}

4.4 将字符转换为字符串

strlib.h库包含函数charToString(ch)

定义函数ReverseString(str),返回一个按str相反次序排列的新字符串:

#include <stdio.h>
#include "strlib.h"

/* Return a reversed string of inputted string. */

/* Function Prototype */
string ReverseString(string s);

/* Main Program */
main() {
    string s;
    s = malloc(1000);
    printf("Input a string need to reverse: ");
    scanf("%s", &s[0]);
    printf("Reversed result is: %s\n", ReverseString(s));
}

/* Function */
string ReverseString(string s) {
    int uplimit, i;
    string result;
    result = "";
    uplimit = StringLength(s) - 1;
    for (i = uplimit; i>=0; i--) {
        result = Concat(result, CharToString(IthChar(s, i)));
    }
    return result;
}

4.5 抽取字符串的一部分

strlib.h库提供了一个函数SubString(s, p1, p2),支持从s中抽取从位置p1到p2之间的字符,包括p1和p2。

例如,函数调用SubString("Hello there!", 1, 3)返回字符串"ell"


定义函数SecondHalf(s),返回一个由s中后半部分字符组成的子串,如果字符串长度是奇数,则包括中间的字符:

#include <stdio.h>
#include "strlib.h"

/* Return the second half of an inputted string. */

/* Function Prototype */
string SecondHalf(string s);

/* Main Program */
main() {
    string s;
    s = malloc(1000);
    printf("Input a string: ");
    scanf("%s", &s[0]);
    printf("%s\n", SecondHalf(s));
}

/* Function */
string SecondHalf(string s) {
    int length;
    length = StringLength(s);
    return (SubString(s, length / 2, length - 1));
}

4.6 比较两个字符串

strlib.h接口提供的StringCompare函数比较两个字符串的ASCII代码。

StringCompare有两个字符串参数s1和s2,它返回一个整数,该整数的符号指出了两个字符串的关系:
按字母顺序,若s1出现在s2前面,则返回一个负整数;
按字母顺序,若s1出现在s2后面,则返回一个正整数;
若两个字符串完全相同,则返回0。

确定按字母顺序s1是否出现在s2的前面,判断语句如下:

if (StringCompare(s1, s2) < 0) ...

常见错误:
当比较字符串的值时,需要使用StringEqualStringCompare,不要使用关系运算符。
C编译器检测不到这个错误,但程序会给出一个完全无法预计的结果。


4.7 在一个字符串内搜索

strlib.h接口提供了两个函数FindcharFindstring,支持搜索一个字符串,看它是否包含某一特定的字符或子串。

4.7.1 FindChar

FindChar的原型是

int Findchar(char ch, string text, int start);

该函数搜索字符串text,从start指定的下标位置开始,寻找字符ch的第一次出现。
如果发现了该字符,返回这个字符的下标位置。
如果在text结束前没有发现这个字符,返回值-1。

例如:

#include <stdio.h>
#include "strlib.h"

/* Main Program */
main() {
    printf("%d\n", FindChar('l', "Hello there", 0));
    printf("%d\n", FindChar('l', "Hello there", 3));
    printf("%d\n", FindChar('l', "Hello there", 4));
    printf("%d\n", FindChar('h', "Hello there", 0));
}
2
3
-1
7

值得注意的是,和字符串比较一样,搜索字符串的函数对大小写是区别对待的。


Findchar实现一个产生首字母缩写(acronym) 的函数,它按次序取一系列单词的首字母形成一个新的单词。

例如,调用函数Acronym("self contained underwater breathing apparatus")将返回"scuba"

#include <stdio.h>
#include <stdbool.h>
#include "strlib.h"

/* Return a new word composed of the first letter of each word. */

/* Function Prototype */
string Acronym(string sentence);

/* Main Program */
main() {
    string sentence;
    sentence = malloc(1000); 
    printf("Input a sentence: ");
    scanf("%[^\n]", &sentence[0]);
    printf("%s\n", Acronym(sentence));
}

/* Function */
string Acronym(string sentence) {
    int idx;
    string word;

    idx = FindChar(' ', sentence, 0);
    word = SubString(sentence, 0, 0);

    while (true) {
        word = Concat(word, SubString(sentence, idx + 1, idx + 1));
        idx = FindChar(' ', sentence, idx + 1);
        if (idx == -1) break;
    }
    return word;
}

4.7.2 FindString

函数FindString(str, text, start)Findchar相似,区别在于第一个参数是字符串。

定义函数ReplaceFirst(str, pattern, replacement)搜索字符串str,将字符串pattern的第一次出现用字符串replacement来取代,将整个新字符串作为函数的返回值返回。如果pattern没有出现,则返回原来的字符串。

具体代码实现如下:

#include <stdio.h>
#include <stdbool.h>
#include "strlib.h"

/* Replace the pattern first time appeared with a inputted word. */


/* Function Prototype */
string ReplaceFirst(string str, string pattern, string replacement);


/* Main Program */
main() {
    string str, pattern, replacement;
    char tmp[100];
    str = malloc(1000);
    pattern = malloc(100);
    replacement = malloc(100); 

    printf("Enter the string to be edited: ");
    scanf("%[^\n]", &str[0]);
    printf("Enter the pattern string: ");
    scanf("%s", &pattern[0]);
    printf("Enter the replacement string: ");
    scanf("%c", &tmp); // temporary statement to clear buffer
    scanf("%[^\n]", &replacement[0]);

    printf("%s\n", ReplaceFirst(str, pattern, replacement));
}


/* Function */
string ReplaceFirst(string str, string pattern, string replacement) {
    string prefix, suffix, result;
    int idx, length;

    idx = FindString(pattern, str, 0);
    
    if (idx != -1) {
        length = StringLength(str);
        prefix = SubString(str, 0, idx - 1);
        suffix = SubString(str, idx + 1, length - 1);
        result = Concat(Concat(prefix, replacement), suffix);
    } else {
        result = str;
    }
        return result;
}   

4.8 大小写转换

strlib.h库中包含两个函数,ConvertToUpperCase(s)ConvertToLowerCase(s),它们将任何字母字符转换为指定的大小写。

例如,调用函数ConvertToUpperCase("Hello, world.")将返回字符串"HELLO, WORLD."

注意,字符串中的任何非字母的字符(如本例中的逗号、空格、句号)不受影响。


4.9 数值转换

4.9.1 IntegerToString / RealToString

strlib.h接口导出两个函数,IntegerToStringRealToString,它们将一个数值转换为字符串表示。

例如,调用IntegerToString(-4)将返回字符串"-4"。

RealToString(d)函数将浮点数d转换为字符串,该字符串的格式类似于由printf用格式码%G的显示结果,有时会产生一个以科学记数法表示的数字。

例如,调用RealToString(3.14)返回“3.14”,而调用RealToString(0.00000000015)将返回"1.5E-10"。

4.9.2 StringToInteger / StringToReal

strlib.h接口还导出了函数StringToIntegerStringToReal,将表示数值的字符串转换为数值。

例如,调用StringToInteger("42")返回整数42。
调用StringToReal("3.14159")返回浮点数3.14159。

如果函数的参数不是合法的数字串,将会报告一个错误。
这两个函数主要用于输入操作。


4.10 效率和strlib.h库

本章中所有函数的实现都是以清晰,而不是以效率作为目标。

许多实现的效率都是相当低的,低得无法适应一些重大的应用。

然而,它们是简明的、可行的、容易理解的。当用这种形式的函数工作时,可以从概念上了解字符串工作的过程。





参考
《C语言的科学和艺术》 —— 第9章 字符串和字符

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值