c函数反转一个字符串

时间:2017-02-13 16:55:45

标签: c arrays string

我试图创建一个获取文本行的函数,然后反转每个单词并返回一个字符串数组。这是我的代码。有些事情显然是错的。对我的错误有任何建议吗?

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;
}

}

2 个答案:

答案 0 :(得分:2)

首先不要使用gets,它可能会导致缓冲区溢出,因为您并不确切知道将要读取的字节数。请改用fgets

其次,不要将malloccalloc的结果强制转换为指针类型。这可能会导致您遗漏一些重要警告。

最重要的是,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()处理每个新字符串以反转字符顺序。