如何使这个(自己的)trim()函数在C中工作?

How do I make this (own) trim() function work in C?

提问人:GooDinosaur 提问时间:9/29/2023 最后编辑:chqrlieGooDinosaur 更新时间:9/29/2023 访问量:93

问:

我必须做一个作业,我必须删除文本末尾和前面的空格。(我不知道是前面还是最后总是有一个。

因此,例如,如果我的输入是“请帮帮我”,那么我的输出必须是“请帮帮我”(前面没有空格)。 我不能再使用我现在正在使用的任何库了。

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

int *pIndexf; // pointer Index front (of the text)
int *pIndexe; // pointer Index end (of the text)

void trim(char source[], int size) {
  
  // Checking the array from the front
  for (int i = 0; i < strlen(source); i++) {
    if (source[i] == ' ') {
        pIndexf = &i;
        break;
    }
  } 

  // Checking the array from behind
  for (int i = strlen(source)-1; i > 0; i--) {
    if (source[i] == ' ') {
       pIndexe = &i;
      break;
    }
  }
}

int main() {
  char source[31] = {" Random text "}; // the array where i store the text i have to manipulate
  char goal[31]; // this is where the trimmed text should be

  trim(source, 31);
  
// Here i would add the source array's elements to the goal list without the spaces in a loop
}

如果我可以使用指针指向函数而不是将它们用作全局变量,那就更好了。main

我希望我的问题是可以理解的。

ps.:我真的不明白指针。

数组 C 函数 指针 修剪

评论

1赞 greg spears 9/29/2023
小帮助:请注意“该函数需要两个参数:源数组(包含带空格的字符串)和目标数组(包含不带空格的字符串)”——我只在您的 trim() 函数中看到“source[]”。that 和整数 'size'。需要一个“dest[]”
1赞 greg spears 9/29/2023
小帮助2:你偏离了保存索引i(&i)地址的轨道 - 它将始终具有相同的地址。您可以安全地转储您的两个 int 指针(pIndexf 等),它们不会为您服务。是的,您可能希望为您的解决方案保存索引 i,但您可以使用另一个整数变量来执行此操作,即:“int save_i;”提示:您可以在不添加任何指针的情况下创建此问题的解决方案:这一切都可以通过使用整数变量访问 char 数组偏移量来完成。
1赞 Fe2O3 9/29/2023
OT:作业建议。这将与标准库的约定相反,例如 , , ...,其参数是 ...trim( src, dest );strcpy()strcat()dest, src

答:

2赞 0___________ 9/29/2023 #1
  1. 你的任务是不同的。您需要目标数组的大小才能使其溢出。

  2. 不要在函数中将全局变量用作临时对象。

  3. 使用正确的尺寸类型。

char *trim(const char *source, char *dest, size_t size)
{
    const char *end = source;
    char *head = dest;
    if(source && dest && size)
    {   
        if(*source)
        {
            while(*(end + 1)) end++;
            while(end > source)
            {
                if(*end != ' ') break;
                else end--;
            }
            while(*source == ' ') source++;
            while(source <= end && --size) *dest++ = *source++;
        }
        *dest = 0;
    }
    return head;
}

评论

0赞 GooDinosaur 9/30/2023
对不起,我也不明白这段代码。为什么函数是指针?例如,您在声明中检查什么?那是什么?为什么你需要一个 That 才能成为 ponter?感谢您的时间和回复!if(*source)*(end + 1)
1赞 0___________ 9/30/2023
它返回指针 - 例如,您可以在下一个函数调用中使用结果,*(ptr + i) === ptr[i]
4赞 nielsen 9/29/2023 #2

赋值说函数必须采用源数组和目标数组,因此函数必须这样做。trim()

剪裁的结果是一个字符串,它可能与源字符串一样长或更短,但永远不会更长。因此,调用方必须始终提供至少与源数组大小相同的目标数组。有了这个使用要求,就不需要知道目标阵列的确切大小。

此外,无需知道源数组的大小,因为 C 字符串将以零结尾。

由于标准库函数使用目标参数位于源之前的约定,因此该函数也可以遵循相同的约定。出于同样的原因,可能会返回指向结果字符串的指针,以便可以在组合表达式中使用该函数。trim()

对于实现本身,策略可以是:

  1. 查找源字符串的长度
  2. 从源字符串的末尾,找到第一个非空格字符(如果存在)。
  3. 从字符串的开头开始,找到第一个非空格字符。
  4. 将第一个字符到最后一个非空格字符的字符复制到目标字符串
  5. 使用零字符终止目标字符串。

在此之后,实现是:

#include <string.h>

char *trim(char *dest, const char *src)
{
   size_t end = strlen(src);                             // Step 1
   while(end > 0 && src[end-1] == ' ') end--;            // Step 2
   size_t begin = 0;
   while(begin < end && src[begin] == ' ') begin++;      // Step 3
   size_t dest_index = 0;
   while(begin < end) dest[dest_index++] = src[begin++]; // Step 4
   dest[dest_index] = 0;                                 // Step 5
   return dest;
}

请注意,指向的是一个指向最后一个非空格字符,而不是最后一个非空格字符本身。这样可以正确处理为零的极端情况(空字符串或包含所有空格的字符串)。endend

使用示例:

const char src[] = " Pls help me";
char dest[sizeof(src)];
trim(dest, src);

评论

0赞 GooDinosaur 9/30/2023
对不起,如果我真的很笨,但我不明白那么多事情。1. 为什么函数是指针?我可以做这样的事情吗?2. 对于第一个和第二个循环,除了迭代之外,你还做了什么吗?您没有写入数组或任何变量,尽管感谢您的时间和回答!3. 在哪里声明,这不是一个函数吗?whiledestsize_t
2赞 nielsen 9/30/2023
@Lolis4TheWin 1.不知道你的意思。为了方便起见,该函数返回一个指针,例如 .2. 这些循环修改并索引到正确的值 3. 在各种标头中定义,例如 .它是一个无符号整数类型,大到足以容纳任何对象的大小,例如任何数组的大小(你可以把它看作是一个,但它对范围有这个额外的保证)。printf("Result: %s\n", trim(dest, src));endbeginsize_tstring.hunsigned
1赞 Fe2O3 9/30/2023
@Lolis4TheWin “3.size_t在哪里声明的,这不是一个函数吗“ 您可能会将其与用于获取对象字节计数的”编译时运算符“混淆。较新的编译器还实现为运行时操作,以考虑 VLA(“可变长度数组”)之类的事情......sizeofsizeof