修剪C中字符串的前导和尾部空白



我一直在搜索堆栈溢出以获取有关函数void strip(char *s)的帮助,但没有找到适合我要求的答案。我尝试过的每一个实现都产生了SEGFAULT

我的想法是增加字符指针s,直到所有空白都被吃掉。然后我有一个指向字符串end末尾的指针。我递减这个指针,直到所有的空白也被吃掉。我已经将我的代码插入gdb中,以确保它所做的一切都正确。然而,当我试图通过插入一个null字符来描绘新子字符串的末尾来截断空白时,我似乎无法使其发挥作用。

参见编辑:

void strip(char *s) {
char *end;
int length = strlen(s);
end = s + length - 1;
while (1) {
if (*s == ' ' || *s == 't' || *s == 'n') {
s++;
} else {
break;
}
}
while (1) {
if (*end == ' ' || *end == 't' || *end == 'n') {
// *end = ''; my current implementation has this uncommented
end--;
} else {
break;
}
}
}
int main(void) {
char *string = "tHello, Worldt";
strip(string);
printf("%sn", string);
}

根据我的理解,至少主函数应该打印Hello, Worldt。拖尾片仍在适当位置。然而,控制台输出tHello, Worldt,就好像指针从未移动过一样。

下面是第2个实现。这个使用两个指针作为开始和结束。然后创建一个全新的字符串供s指向。这个字符串也只打印出tHello, Worldt。另一方面,GDB将temp视为Hello, World

void strip(char *s) {
char *start, *end;
int length = strlen(s);
end = s + length - 1;
while (1) {
if (*start == ' ' || *start == 't' || *start == 'n') {
start++;
} else {
break;
}
}
while (1) {
if (*end == ' ' || *end == 't' || *end == 'n') {
end--;
} else {
break;
}
}
char temp[length];
int index = 0;
while (start <= end) {
temp[index++] = *start;
start++;
}
temp[index] = '';
s = temp;
}

编辑

void strip(char *s)
{
char *end;
int length = strlen(s);
end = s + length - 1;
// while a character is a space AND didn't reach the end
while (s != NULL && isspace(*s))
{
s++;
}
// While end has not passed ptr s AND is a space
while (end > s && isspace(*end))
{
// replace the whitespace
*end = '';
end--;
}
}

int linesff(const char *s, char **lines)
{
FILE *fp;
if ((fp = fopen(s, "r")) == NULL)
{
printf("Cannot open file: %sn", s);
return -1;
}
// max buffer size
char buf[MAX_C];
int index = 0;
// while Not EOF
while (!feof(fp))
{
// get a line to put in buf
fgets(buf, MAX_C, fp);
// strip buf
strip(buf);
// if buf is greater than 1, meaning line has characters left
if (strlen(buf) > 1)
{
// add buf at index
lines[index] = buf;
index++;
}
}
// return the count
return index;
}

Strip是lineff的一个辅助函数,它将去除空白。**lines是这样创建的:

for (int i = 0; i < MAX_L; i++)
lines[i] = malloc(MAX_C);

我仍然无法修改buf以保持正确剥离的字符串。

存在一些问题。一旦程序离开strip函数,temp就会被解除分配,因此s将指向无效内存。但s也是该函数的本地函数,因此在最后将其设置为任何值都是毫无意义的。例如,您需要使用malloc在堆中分配内存,并将temp内容复制到堆中,然后返回指向该内存位置的指针。堆中分配的内存将一直存在,直到您没有通过调用它们的free(...)来释放它们。

这样它将工作

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* strip(char *s) {
char *start, *end;
int length = strlen(s);
start = s;
end = s + length - 1;
while (1) {
if (*start == ' ' || *start == 't' || *start == 'n') {
start++;
} else {
break;
}
}
while (1) {
if (*end == ' ' || *end == 't' || *end == 'n') {
end--;
} else {
break;
}
}
char temp[length + 1];
int index = 0;
while (start <= end) {
temp[index++] = *start;
start++;
}
temp[index] = '';
char *result = malloc(strlen(temp) + 1);
if (result == NULL)  // check if malloc failed
return NULL;
strcpy(result, temp);
return result;
}
int main(void) {
char *string = "tHello, Worldt";
char *result_string = strip(string);
// check the return value, if it NULL then something went wrong
if (result_string != NULL) {
printf("%sn", result_string);
free(result_string);
} else {
printf("Error occuredn");
}
return 0;
}
char *string = "tHello, Worldt";

如果您这样做,string将是一个指向常量字符串的指针,这意味着您不能用*pointer更改字符串内容。

为了更改字符串,您必须在堆栈或堆中分配字符串,如:

char string[100] = "tHello, Worldt";

最新更新