鉴于此字符串"红色,蓝色,绿色"创建一个包含这些颜色作为其元素的数组。我在下面编写的代码有效,但当我将颜色的第一个字母更改为大写时,我得到输出 - 红色,蓝色\ 301-!Wree \ 316。如何使这个代码更加动态,以便使用以大写字母开头的单词?谢谢。
#include <stdio.h>
#include <stdlib.h>
int findLength(char string[]){
int l =0;
for(l = 0; string[l]!='\0'; l++){
}
return l;
};
char *stringToArray(char string[]){
int i = 0;
int j = 0;
char c = ',';
int n = 0;
int l = findLength(string);
char *str = (char *)malloc(l * sizeof(char));
while(string[i] != l){
if(string[i] == c || string[i] != '\0'){
for(n = j; n < i; n++){
str[j++] += string[n];
}
}
i++;
}
printf("%s\n", str);
str = '\0';
return str;
}
int main(int argc, const char * argv[]) {
char *string = "red, blue, green";
//char *string = "Red, Blue, Green";
char *str = stringToArray(string);
free(str);
return 0;
}
答案 0 :(得分:0)
奇怪的行为与你的字符串是否有upparcase字母没有任何关系。 stringToArray
中循环的终止条件是错误的:
int l = findLength(string);
while (string[i] != l) ...
条件应为
while (i < l) ...
或者,正如您在findLength
中使用的那样:
while (string[i] != '\0') ...
因为条件错误 - l
在你的情况下是16而且没有一个字母的ASCII值是16 - 你超出了字符串的有效范围,这导致了未定义的行为。
目前,您只需将旧字符串复制到新字符串即可,但这种方式非常奇怪。你的内部循环使用三个变量,其中两个变量递增。这非常令人困惑。它可能也不符合您的想法,因为条件:
if (string[i] == c || string[i] != '\0') ..
对于字符串的所有字母都为true,前提是opuer循环应该只考虑有效字符,但不包括字符串的结尾。
最后,如果要复制字符串,则应为终止字符分配süpace:
char *str = malloc(l + 1);
如果要追加最后的空字符:
str = '\0';
实际上,您将while分配的字符串设置为null,这会导致内存泄漏。 (free
中的main
不会产生错误,因为free
可以合法地将'NULL`作为参数。)相反,请使用:
str[l] = '\0';
通过这些修复,您现在拥有一个复制原始字符串的程序。 (POSIX)库函数strdup
更有效地完成了这项工作。如果要返回一个字符串数组,则必须反映函数以返回指向字符指针的指针。
以下是该行为的可能实现。 (它使用这种方法为堆上的所有内容分配内存。如果你总是期望三个短字符串可能不是最好的解决方案。)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char **stringToArray(const char *str)
{
char **res;
const char *p = str;
int n = 0;
while (p) {
p = strchr(p, ',');
if (p) p++;
n++;
}
res = malloc((n + 1) * sizeof(*res));
p = str;
n = 0;
while (p) {
const char *begin;
size_t len;
while (*p == ' ') p++;
begin = p;
p = strchr(p, ',');
if (p) {
len = p - begin;
p++;
} else {
len = strlen(begin);
}
res[n] = malloc(len + 1);
memcpy(res[n], begin, len);
res[n][len] = '\0';
n++;
}
res[n] = NULL;
return res;
}
int main(int argc, const char * argv[])
{
char *str = "Vermilion, Ultramarine, Chartreuse";
char **res = stringToArray(str);
int i = 0;
for (i = 0; res[i]; i++) {
puts(res[i]);
free(res[i]);
}
free(res);
return 0;
}
答案 1 :(得分:0)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int findLength(char string[]){
int l = 1;
for (int i = 0; string[i] != '\0'; i++){
if (string[i] == ',')// to check the end of a color
l++;
}
return l;
};
char **stringToArray(char string[]){//added a * for array of satrings
int i = 0;
int j = 0;
char c = ',';
int n = 0;
int l = findLength(string);
char **str = (char **)malloc(l * sizeof(char*)+l);
char *pos = string;
for (int i = 0; i < l-1; i++) //getting each color to the array
{
char *c =strchr(string, ',');
int index = c - pos;
string[index] = 0;
str[i] = _strdup(pos); //copying the color to the array
pos = c + 1;
string = string +1 +index; // next color
}
str[l - 1] = _strdup(pos); //copying last color
for (int i = 0; i < l; i++) //printing the results
{
printf("%s\n",str[i]);
}
return str;
}
int main(int argc, const char * argv[]) {
char string[] = "red,blue,green"; //deleted spaces
char **str = stringToArray(string);
getchar();
free(str);
return 0;
}
还添加了评论供您理解。