我正在创建一个将在一个字符串数组中搜索的程序,并且对于每个字符串,它将搜索指定的char。如果它找到了char,请将其删除。在这个例子中,我想删除字符' r'。
以下是代码:
void convertStrings(char **line) {
for (int str = 0; str < MAX_LINE_LENGTH; ++str) {
for (int ch = 0; ch < MAX_STR_LENGTH; ++ch) {
if (line[str][ch] == 'r') {
removeChar(line[str], 'r');
}
}
}
}
void removeChar(char *str, char c) {
int i = 0;
int j = 0;
while (str[i]) {
if (str[i] != c) {
str[j++] = str[i];
}
i++;
}
str[j]=0;
}
我不确定删除字符的算法是否正确,但主要错误是在其他地方。更具体地说,我在行中得到了一个分段错误:
if (line[str][ch] == 'r') {
为什么我会遇到段错误?另外,removeChar算法是否正确?
这是我的主要功能:
int main() {
char line[3][10] = {"pep", "rol", "rak"};
printf("%s\n", line[1]);
convertStrings(line);
printf("%s\n", line[1]);
return 0;
}
提前致谢。
答案 0 :(得分:2)
此代码适用于我的编译器:
#include<stdio.h>
#include<conio.h>
#define MAX_LINE_LENGTH 1024
#define MAX_STR_LENGTH 4
void removeChar(char *str, char c) {
int i = 0;
int j = 0;
while (str[i]) {
if (str[i] != c) {
str[j++] = str[i];
}
i++;
}
str[j]=0;
}
void convertStrings(char line[][MAX_STR_LENGTH]) { //change 1
for (int str = 0; str < MAX_LINE_LENGTH; ++str) {
for (int ch = 0; ch < MAX_STR_LENGTH; ++ch) {
if (line[str][ch] == 'r') {
removeChar(line[str], 'r');
}
}
}
}
int main() {
char line[3][MAX_STR_LENGTH] = {"pep", "rol", "rak"}; //change 2
printf("%s\n", line[1]);
convertStrings(line);
printf("%s\n", line[1]);
getch();
return 0;
}
答案 1 :(得分:1)
这是因为line[str][ch]
并不存在您为str
和/或ch
提供的所有价值。
您应该检查MAX_LINE_LENGTH
和MAX_STR_LENGTH
的值,并确保它们是正确的。
答案 2 :(得分:1)
seg错误可能是因为您使用常量“MAX_LINE_LENGTH”和“MAX_STR_LENGTH”,但可能有行长度或字符串长度。我会在第一个for循环中使用数组的长度代替“MAX_LINE_LENGTH”,而使用数组的长度[str]而不是“MAX_STR_LENGTH”。除非您搜索的每个数组都有“MAX_LINE_LENGTH”并且每个字符串都有“MAX_LINE_LENGTH”,否则您将收到设置错误。希望这有帮助!
编辑:你可以通过除去数组的大小和元素类型的大小来找到数组的长度。
sizeof(array)/sizeof(array[0])
查找char指针的大小基本上是相同的过程。
答案 3 :(得分:1)
你有阵列
char line[3][10] = {"pep", "rol", "rak"};
将它传递给函数时,它会转换为char(*)[10]
类型的指针。所以改变
void convertStrings(char **line) {
到
void convertStrings(char (*line)[10]) {
或
void convertStrings(char line[][10]) {
数组数组(2D数组)无法转换为指向指针的指针(在本例中为char**
)
另一个问题是you mention that MAX_LINE_LENGTH
是1024而MAX_STR_LENGTH
是4.这是错误的,因为循环将迭代并且您访问无效的内存位置。您应该将MAX_LINE_LENGTH
设为3,将MAX_STR_LENGTH
设为4,因为有3个字符串,每个字符串有4个字符。
您还可以将这些变量作为参数传递给函数convertStrings
。更改在convertStrings
:
void convertStrings(char (*line)[10], int MAX_LINE_LENGTH, int MAX_STR_LENGTH) {
或
void convertStrings(char line[][10], int MAX_LINE_LENGTH, int MAX_STR_LENGTH) {
并使用
从main
调用该函数
convertStrings(line, sizeof(line)/sizeof(*line), sizeof(*line)/sizeof(**line)); // `/sizeof(**line)` is 1 and is not needed
<小时/> 更好的方法是使用
void convertStrings(int MAX_LINE_LENGTH, int MAX_STR_LENGTH, char line[][MAX_STR_LENGTH]) {
或
void convertStrings(int MAX_LINE_LENGTH, int MAX_STR_LENGTH, char (*line)[MAX_STR_LENGTH]) {
并使用
调用该函数convertStrings(sizeof(line)/sizeof(*line), sizeof(*line)/sizeof(**line), line); // `/sizeof(**line)` is 1 and is not needed
这样您就可以避免在函数中使用幻数10.
<小时/> 你肯定会从你的编译器得到一些警告。注意它们。如果您没有收到警告,请在编译器中启动警告并添加警告标志(如GCC中的
-Wall
)。
BTW,你可以从strchr
查看string.h
函数来查找字符串中是否存在字符。
答案 4 :(得分:1)
你得到一个段错误,因为数组line
包含的字符串指针少于MAX_LINE_LENGTH
,或者因为至少有一个指向字符串包含的字符数少于MAX_STR_LENGTH
;更有可能是后者。
除了假定固定长度的固定数量的字符串之外,最好将实际数量的字符串作为参数传递。或者,您可以在列表末尾添加NULL
作为哨兵值。
此外,没有理由假设每个字符串是固定长度。寻找终止字符('\0'
)以识别您何时到达终点。例如:
void convertStrings(char **line) {
for (char **l = line; *l != NULL; l += 1) {
for (int ch = 0; (*l)[ch]; ch += 1) {
if ((*l)[ch] == 'r') {
removeChar(*l, 'r');
}
}
}
}
您的removeChar()
功能看起来不错。
请注意,有些库函数可以帮助解决这个问题(例如strchr()
),并且可以进行各种效率改进(例如只传递给removeChar()
字符串尾部,从第一次出现的角色开始删除)。
答案 5 :(得分:1)
为什么要检查两次是否遇到'r'字符? (在两个功能中) 检查一次就足够了。
检测char的函数和删除它的函数?
我会这样做的:
#include <string.h>
#include <stdio.h>
void convertStrings(char *line);
void removeChar(char *str);
int main(int argc, char *argv[]) {
if (argc == 2)
{
printf("%s\n", argv[1]);
convertStrings(argv[1]);
printf("%s\n", argv[1]);
}
return (0);
}
void convertStrings(char *line)
{
for (int i = 0; line[i] != '\0'; i++)
{
if (line[i] == 'r') removeChar(&(line[i]));
}
}
void removeChar(char *str)
{
int i;
i = 0;
while (str[i] != '\0')
{
str[i] = str[i + 1];
i++;
}
}
但这是另一个只有一个功能的解决方案:
void convertStringsbis(char *line)
{
int delta;
int i;
i = 0;
delta = 0;
while (line[i++ + delta] != '\0')
{
if (line[i + delta] == 'r')
delta++;
line[i] = line[i + delta];
}
}