我试图创建一个获取文本行的函数,然后反转每个单词并返回一个字符串数组。这是我的代码。有些事情显然是错的。对我的错误有任何建议吗?
char** function(char* str, int* pn)
{
char temp[21];
int n_of_spaces = 0, i = 0, d = 0;
for (int i = 0; str[i]; i++)
if (str[i] == ' ')
n_of_spaces++;
*pn = n_of_spaces + 1; //should be number of words
char** s = (char**)calloc(*pn, sizeof(char*));
while (str[i])
{
d = 0;
if (i != 0)
i++;
while (str[i] != ' ' && str[i] != 0)
{
i++;
d++;
}
for (int j = 0; j < d; j++)
temp[j] = str[i];
for (int k = 0; k < *pn; k++)
{
s[k] = (char*)calloc(d + 1, sizeof(char));
strcpy(s[k], temp);
invert(s[k]); //inverts a word
}
}
return s;
}
//主干
int main()
{
int n_of_words;
char line[100];
gets(line);
char** s = function(line, &n_of_words);
for (int i = 0; i < n_of_words; i++)
{
puts(s[i]);
free(s[i]);
}
free(s);
return 0;
}
void invert(char* s)
{
int t;
for (int i = 0, j = strlen(s) - 1; i < j; i++, j--)
{
t = s[i];
s[i] = s[j];
s[j] = t;
}
}
答案 0 :(得分:2)
首先不要使用gets
,它可能会导致缓冲区溢出,因为您并不确切知道将要读取的字节数。请改用fgets
。
其次,不要将malloc
和calloc
的结果强制转换为指针类型。这可能会导致您遗漏一些重要警告。
最重要的是,Yuriy Ivaskevych说你应该更好地使用strtok
函数来分割你的字符串。
完成所有这些后,temp
变量的静态大小为21,当您将数据复制到其中时,该变量可能会溢出。当您实际复制数据时,不要设置字符串终止字符\0
。因此,当您调用strcpy
时,它无法找到字符串的结尾,并且您将获得未定义的行为
答案 1 :(得分:0)
这不会反转每个单词,但它说明了如何反转输入行。 (即提供一个解决标题问题的示例, c函数来反转字符串)它旨在显示一种简化的方法,并希望您可以使用它来扩展到您想要做的事情。
请注意以下事项:
1)main
函数的原型发生了变化
2)function()
的原型发生了变化
3)使用strdup()
而不是calloc()。 (简化)
4)所有工作都在function()
完成,即没有invert()
。
这将编译并运行以反转最多99个字符的输入字符串。
char* function(char* str, int* pn)
{
if(!str) return "";
char *newStr = strdup(str);
int len, i=0;
len = strlen(str);
while(str[i])
{
newStr[len-1-i]=str[i];
i++;
}
str[i]=0;
strcpy(str, newStr);
free(newStr);
*pn = i-1;
return str;
}
//heres main
int main(void)
{
int n_of_words;
char line[100];
char line2[100];
gets(line);
strcpy(line2, function(line, &n_of_words));
printf( "reversed line: %s", line2);
return 0;
}
编辑(发表评论)
将字符串分解为 字的建议方法 :
1)使用两步读取,首先读取计数空格和最长字。
2)使用第一步中的信息为 count 字符串创建空间,每个最长 +1长。建议使用单独的函数来创建/释放此内存,例如:
char ** Create2DStr(int numStrings, int maxStrLen)
{
int i;
char **a = {0};
a = calloc(numStrings, sizeof(a));
for(i=0;i<numStrings; i++)
{
a[i] = calloc(maxStrLen + 1, 1);
}
return a;
}
void free2DStr(char ** a, int numStrings)
{
int i;
for(i=0;i<numStrings; i++)
{
if(a[i]) free(a[i]);
}
free(a);
}
3)通过原始字符串读取的第二个内容是将其分解为&#34; words&#34;并放置每个&#34;字&#34;进入你创建的字符串。以循环计数 +1次执行此操作。有许多方法可以工作,strtok(...)
解析空格,或逐字节字符分配到每个字符串,每次byte==space
索引循环。
4)在后续循环中,通过上面的function()
处理每个新字符串以反转字符顺序。