【问题标题】:two C functions trying to return the first word in a string两个 C 函数试图返回字符串中的第一个单词
【发布时间】:2026-01-04 19:10:01
【问题描述】:

我创建了以下两个函数。第一个,eatWrd,返回字符串中的第一个单词,不带任何空格,并从输入字符串中删除第一个单词:

MAX 是一个代表字符串最大长度的数字

char* eatWrd(char * cmd)
{
  int i = 0;        //i will hold my place in cmd
  int count = 0;    //count will hold the position of the second word
  int fw = 0;       //fw will hold the position of the first word
  char rest[MAX]; // rest will hold cmd without the first word
  char word[MAX]; // word will hold the first word

  // start by removing initial white spaces
  while(cmd[i] == ' ' || cmd[i] == '\t'){
    i++;
    count++;
    fw++;
  }

  // now start reading the first word until white spaces or terminating characters
  while(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '\n' && cmd[i] != '\0'){
    word[i-fw] = cmd[i];
    i++;
    count++;
  }
  word[i-fw] = '\0';

  // now continue past white spaces after the first word
  while(cmd[i] == ' ' || cmd[i] == '\t'){
    i++;
    count++;
  }

  // finally save the rest of cmd
  while(cmd[i] != '\n' && cmd[i] != '\0'){
    rest[i-count] = cmd[i];
    i++;
  }
  rest[i-count] = '\0';

  // reset cmd, and copy rest back into it
  memset(cmd, 0, MAX);
  strcpy(cmd, rest);

  // return word as a char *
  char *ret = word;
  return ret;
}

第二个,frstWrd,只返回第一个单词,不修改输入字符串:

// this function is very similar to the first without modifying cmd
char* frstWrd(char * cmd)
{
  int i = 0;
  int fw = 0;
  char word[MAX];

  while(cmd[i] == ' ' || cmd[i] == '\t'){
    i++;
    fw++;
  }

  while(cmd[i] != ' ' && cmd[i] != '\t' && cmd[i] != '\n' && cmd[i] != '\0'){
    word[i-fw] = cmd[i];
    i++;
  }
  word[i-fw] = '\0';

  char *ret = word;
  return ret;
}

为了测试函数,我使用 fgets 从 User(me) 读取一个字符串,然后打印三个字符串(frstWrd(input)、eatWrd(input)、eatWrd(input))。我本来希望给定一个字符串,例如“my name is tim”,程序会打印“my my name”,但它会打印第三个单词三次,“is is is”:

// now simply test the functions
main()
{
  char input[MAX];
  fgets(input, MAX - 1, stdin);
  printf("%s %s %s", frstWrd(input), eatWrd(input), eatWrd(input));
}

我一遍又一遍地检查我的函数,但看不到错误。我相信关于 printf,或者关于在另一个函数中使用多个字符串修改函数作为参数,我完全不知道一些事情。任何见解都会有所帮助,谢谢。

【问题讨论】:

  • 只有一长段描述您的问题很难阅读。尝试以某种方式拆分信息。
  • 相关:您应该想知道在您的printf() 参数中是否对这三个函数调用的执行顺序有任何保证。 (剧透:没有这样的保证)。您的返回值中显然存在 未定义的行为(请参阅下面的 Volands 回答)。
  • ty,我个人认为现在好多了。
  • 重复,*.com/questions/25798977/…(以及其他十几个线程)

标签: c string function printf word


【解决方案1】:

我看到restword 是函数eatWrd 中的局部变量。因此,在函数之外返回指向此类内存的指针是不好的做法。

编辑 1:

你也应该明白,那一行

printf("%s %s %s", frstWrd(input), eatWrd(input), eatWrd(input));

函数eatWrd(input) 可以被第一个调用(在frstWrd(input) 之前)。

编辑 2:

这在函数eatWrd中很有用

  //char rest[MAX]; // rest will hold cmd without the first word
  char * rest = (char*) malloc(MAX);

而新的主要让我们成为:

int main()
{
  char input[MAX];
  fgets(input, MAX - 1, stdin);
  printf("%s ", frstWrd(input));
  printf("%s ", eatWrd(input));
  printf("%s\n", eatWrd(input));
}

最后是我对frstWrd 的解决方案(只是为了展示标准函数如何有用):

char* frstWrd(char * cmd)
{
  char * word = (char *) malloc(MAX);
  sscanf(cmd, "%s", word);
  return word;
}

【讨论】:

  • 好的,谢谢,有什么好方法可以从 c 函数返回字符串?
  • @quigs 您也可以只malloc() 字符串所需的内存并返回。这种方法的最大优点是您不需要使用具有给定大小的预分配缓冲区,而是调用分配内存来适应字符串。这消除了巨大的误差源。这更加方便,因为已经有一些标准函数(POSIX-2008 标准)返回 malloc'ed 字符串(asprintf()strdup() 等)。这些通常可以用来做繁重的工作。您唯一需要记住的是free() 电话。
  • @quigs:char* 类型的函数返回指针,使用函数完成后可用的内存非常重要。所以有三种选择: a) 从堆中使用内存(使用 malloc 或类似函数分配); b)使用静态局部变量(内存将被保留并在函数工作之间可用); c)返回指向全局变量占用的内存或外部分配的内存的指针(例如,您的示例中的 cmd 指向的内存)。
最近更新 更多