【发布时间】:2021-05-17 19:44:29
【问题描述】:
我正在尝试解决一个挑战,但我不知道我的代码出了什么问题!
挑战是:
- 创建一个将字符串拆分为单词的函数。
- 分隔符是空格、制表符和换行符。
- 此函数返回一个数组,其中每个框包含一个由单词表示的字符串地址。此数组的最后一个元素应等于 0,以强调数组的末尾。
- 您的数组中不能有任何空字符串。得出必要的结论。 不能修改给定的字符串。
- 注意:唯一允许的函数是
malloc()
错误/问题:
我遇到了这个问题,我试图解决它,但我无法确定出了什么问题。
我创建了一个名为 split_whitespaces() 的函数来完成这项工作。
当我在 split_whitespaces 函数中打印字符串数组时,我得到以下输出:
Inside the function:
arr_str[0] = This
arr_str[1] = is
arr_str[2] = just
arr_str[3] = a
arr_str[4] = test!
当我在 main 函数中打印字符串数组时,我得到以下输出:
Inside the main function:
arr_str[0] = @X@?~
arr_str[1] = `X@?~
arr_str[2] = just
arr_str[3] = a
arr_str[4] = test!
我创建了一个函数 word_count 来计算输入字符串中有多少个单词,这样我就可以使用 malloc 和 word_count + 1(空指针)分配内存。
int word_count(char *str) {
int i;
int w_count;
int state;
i = 0;
w_count = 0;
state = 0;
while (str[i]) {
if (!iswhitespace(str[i])) {
if (!state)
w_count++;
state = 1;
i++;
} else {
state = 0;
i++;
}
}
return (w_count);
}
还有一个名为 strdup_w 的函数来模仿 strdup 的行为,但只针对单个单词:
char *strdup_w(char *str, int *index) {
char *word;
int len;
int i;
i = *index;
len = 0;
while (str[i] && !iswhitespace(str[i]))
len++, i++;;
word = (char *) malloc(len + 1);
if (!word)
return (NULL);
i = 0;
while (str[*index]) {
if (!iswhitespace(str[*index])) {
word[i++] = str[*index];
(*index)++;
} else
break;
}
word[len] = '\0';
return (word);
}
这是我的完整代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **split_whitespaces(char *str);
char *strdup_w(char *str, int *index);
int word_count(char *str);
int iswhitespace(char c);
int main(void) {
char *str = "This is just a test!";
char **arr_str;
int i;
i = 0;
arr_str = split_whitespaces(str);
printf("\nOutside the function:\n");
while (arr_str[i]) {
printf("arr_str[%d] = %s\n", i, arr_str[i]);
i++;
}
return (0);
}
char **split_whitespaces(char *str) {
char **arr_str;
int i;
int words;
int w_i;
i = 0;
w_i = 0;
words = word_count(str);
arr_str = (char **)malloc(words + 1);
if (!arr_str)
return (NULL);
printf("Inside the function:\n");
while (w_i < words) {
while (iswhitespace(str[i]) && str[i])
if (!str[i++])
break;
arr_str[w_i] = strdup_w(str, &i);
printf("arr_str[%d] = %s\n", w_i, arr_str[w_i]);
w_i++;
}
arr_str[words] = 0;
return (arr_str);
}
char *strdup_w(char *str, int *index) {
char *word;
int len;
int i;
i = *index;
len = 0;
while (str[i] && !iswhitespace(str[i]))
len++, i++;;
word = (char *)malloc(len + 1);
if (!word)
return (NULL);
i = 0;
while (str[*index]) {
if (!iswhitespace(str[*index])) {
word[i++] = str[*index];
(*index)++;
} else
break;
}
word[len] = '\0';
return (word);
}
int word_count(char *str) {
int i;
int w_count;
int state;
i = 0;
w_count = 0;
state = 0;
while (str[i]) {
if (!iswhitespace(str[i])) {
if (!state)
w_count++;
state = 1;
i++;
} else {
state = 0;
i++;
}
}
return (w_count);
}
int iswhitespace(char c) {
if (c == ' ' || c == '\t' || c == '\n' || c == '\r')
return (1);
return (0);
}
对不起,如果有什么问题,这是我第一次尝试寻求帮助。
【问题讨论】:
-
建议:不要为 C 代码标记 C++,反之亦然。当然,C 和 C++ 程序员之间有很多交叉,你会吸引更多的目光关注这个问题,但并不是所有的眼睛都感兴趣,他们可以像感兴趣的人一样对问题的优点进行投票。
-
在
split_whitespaces中,尝试将arr_str = (char **) malloc(words + 1);更改为arr_str = malloc(sizeof(*arr_str) * (words + 1));正如你所拥有的那样,words是一个 count 而 not byte length,所以你没有分配足够的空间,所以你有 UB。 -
@CraigEstey 非常感谢!但是看了一些教程,他们说 malloc 接受一个参数,即要分配的内存大小(以字节为单位),这就是我为 5 个字节分配内存的原因!你能告诉我在没有 sizeof() 函数的情况下使用 malloc 的替代方法吗?我会很感激的。
-
为什么要避开sizeof函数?这没有多大意义
-
@lulle 在挑战/练习中他们告诉我们唯一允许的功能是
malloc(),我想这是一种迫使我们自己尝试解决的方法..