``` #include <stdio.h> #include <string.h> #define MAXLEN 100 typedef struct { char data[MAXLEN]; int length; } SqString; /* 初始化定长顺序串 */ void InitStr(SqString* s, char* str) { int i; for (i = 0; str[i] != '\0'; i++) { s->data[i] = str[i]; } s->length = i; // 存储实际长度 } /* BF模式匹配算法 */ int BF(SqString s,SqString t) { int i=0,j=0; while(i<s.length&&j<t.length) { if(s.data[i]==t.data[j]) { i++; j++; } else { i=i-j+1; j=0; } } return (j >= t.length) ? (i - t.length) : -1; } int main() { SqString S, T; InitStr(&S, "aaabbbababaabb"); // 主串初始化 InitStr(&T, "abaa"); // 子串初始化 int result = BF(S, T); if (result != -1) { printf("匹配成功,起始位置:%d\n", result); } else { printf("匹配失败\n"); } return 0; }```改为用户自行输入主串和字串的形式
时间: 2025-04-07 14:13:10 浏览: 34
<think>好的,我现在需要帮用户将原来的C语言代码改为允许用户自行输入主串和子串的形式。首先,我得仔细看看用户提供的代码结构。原代码中,主串和子串都是硬编码的,使用了InitStr函数来初始化SqString结构体。用户的目标是让程序运行时,用户可以自己输入这两个字符串。
第一步,我需要理解现有的数据结构。SqString结构体有一个data数组,长度MAXLEN是100,还有一个length记录实际长度。InitStr函数将传入的字符串复制到data数组中,并设置length。BF算法函数是标准的暴力匹配实现,返回匹配的位置或-1。
接下来,考虑如何让用户输入主串和子串。原来的InitStr函数是从给定的char* str拷贝到结构体,现在需要替换为从标准输入读取。但要注意,用户输入的字符串可能会超过MAXLEN,所以需要处理长度限制的问题。比如,使用fgets函数来读取输入,这样可以防止缓冲区溢出。然后,需要去掉可能的换行符,并正确设置length属性。
所以,修改InitStr函数可能不太合适,因为原来的函数是直接拷贝字符串,而用户输入需要不同的处理方式。或者,可以保留InitStr函数,但另外编写输入函数。不过,可能更简单的方法是在main函数中直接读取用户输入,处理后再初始化SqString。
例如,在main函数中,用户输入主串和子串,然后调用InitStr。但原InitStr函数使用的是char*参数,可能直接传递输入缓冲区即可。不过要注意,用户输入可能包含换行符,需要用fgets读取,并替换掉结尾的换行符为'\0'。例如:
char str[MAXLEN];
printf("请输入主串:");
fgets(str, MAXLEN, stdin);
str[strcspn(str, "\n")] = '\0'; // 去掉换行符
InitStr(&S, str);
同样的处理用于子串。但需要确认InitStr函数是否正确处理这种情况。原来的InitStr函数在循环中复制直到遇到'\0',而fgets读取的字符串后面如果有换行符被替换为'\0',所以没问题。
接下来,测试输入的情况。比如,用户输入的主串长度不能超过MAXLEN-1,因为fgets会保留一个位置给'\0',而SqString的data数组是MAXLEN大小,所以应该没问题。
另外,原来的代码中,InitStr的循环条件是str[i] != '\0',所以只要用户输入的字符串长度不超过MAXLEN-1,就能正确复制。因为MAXLEN是100,所以最大允许99个字符,加上结尾的'\0'刚好100。但fgets读取最多MAXLEN-1个字符,包括换行符,所以需要替换掉换行符,保证字符串正确结束。
那么,修改main函数中的初始化部分,用fgets读取用户输入的主串和子串,处理换行符后,再调用InitStr。这样就能实现用户自行输入的功能。
接下来,需要检查BF算法是否正确处理不同的输入情况。比如,当子串长度超过主串时,返回-1,这应该是正确的。
测试案例:比如主串输入"aaabbbababaabb",子串"abaa",应该和原代码结果一致。或者输入其他例子,如主串"hello world",子串"world",应该返回匹配的位置。
可能的问题:如果用户输入的字符串长度超过MAXLEN-1,会被截断,但代码不会有错误,只是处理前99个字符。需要确保用户知道输入长度限制。
综上,修改的主要步骤是在main函数中,替换原来的硬编码字符串,改为使用fgets读取用户输入,处理换行符,然后调用InitStr初始化结构体。其他部分无需改动。</think>以下是修改后的代码,允许用户自行输入主串和子串:
```c
#include <stdio.h>
#include <string.h>
#define MAXLEN 100
typedef struct {
char data[MAXLEN];
int length;
} SqString;
/* 初始化定长顺序串 */
void InitStr(SqString* s, char* str) {
int i;
for (i = 0; str[i] != '\0'; i++) {
s->data[i] = str[i];
}
s->length = i; // 存储实际长度
}
/* BF模式匹配算法 */
int BF(SqString s, SqString t) {
int i = 0, j = 0;
while (i < s.length && j < t.length) {
if (s.data[i] == t.data[j]) {
i++;
j++;
} else {
i = i - j + 1;
j = 0;
}
}
return (j >= t.length) ? (i - t.length) : -1;
}
int main() {
SqString S, T;
char mainStr[MAXLEN], subStr[MAXLEN];
// 用户输入主串
printf("请输入主串(最多%d个字符): ", MAXLEN - 1);
fgets(mainStr, MAXLEN, stdin);
mainStr[strcspn(mainStr, "\n")] = '\0'; // 移除换行符
InitStr(&S, mainStr);
// 用户输入子串
printf("请输入子串(最多%d个字符): ", MAXLEN - 1);
fgets(subStr, MAXLEN, stdin);
subStr[strcspn(subStr, "\n")] = '\0'; // 移除换行符
InitStr(&T, subStr);
// 执行模式匹配
int result = BF(S, T);
if (result != -1) {
printf("匹配成功,起始位置:%d\n", result);
} else {
printf("匹配失败\n");
}
return 0;
}
```
修改说明分步解释:
1. **输入处理优化**
- 使用`fgets()`替代硬编码输入,更安全地读取用户输入
- 添加`strcspn()`函数移除换行符,避免影响匹配结果
- 保留原数据结构`SqString`和`BF算法`,确保算法稳定性
2. **交互式界面**
- 添加`printf`提示用户输入
- 输入长度限制提示(最多99个字符),防止溢出
3. **安全性保障**
- `fgets()`会自动限制输入长度,防止缓冲区溢出
- 输入内容通过`InitStr`初始化时会自动截断到合法长度
测试案例:
```
请输入主串:hello world
请输入子串:world
匹配成功,起始位置:6
请输入主串:algorithm
请输入子串:xyz
匹配失败
```
该实现完整保留了原算法的核心逻辑,仅扩展了用户交互功能,是学习字符串匹配算法的典型实践案例。
阅读全文
相关推荐



















