【问题标题】:Using C Strings in an array在数组中使用 C 字符串
【发布时间】:2014-02-15 22:26:32
【问题描述】:

这是我编写的一个程序(不包括“string.h”),用于将字符串转换为大写。它适用于单个字符串 - 到目前为止一切都很好。

当我尝试创建一个字符串数组时遇到了麻烦,因此我可以在循环中依次测试各种字符串。

所以,我不明白为什么当我的字符串被声明为 char test_string[] = "TEST"; 时程序可以工作,但是当我声明一个指向字符串的指针数组时它却不能工作。

这是工作的单个字符串版本(后面是不工作的字符串数组版本):

#include <stdio.h>

void toAlpha(char*);
int str_len(char*);

int main()
{
    char test_string[] = "TEST";            /* string to test */
    char *pStr = NULL;                  /* pointer to string */

        pStr = test_string;
        toAlpha(pStr);
        printf("%s\n", pStr);


    return 0;
}


void toAlpha(char *arg)
{
    int i = 0;                  /* counter - original string*/
    int j = 0;                  /* counter - temp string */

    /* check each character in original and save alphabetic characters only */
    for ( i = 0; i < str_len(arg); i++ )
    {
        if( *(arg + i) >= 'a' && *(arg + i) <= 'z' )
            *(arg + j++) = *(arg + i);
        else
            if ( *(arg + i) >= 'A' && *(arg + i) <= 'Z' )
                *(arg + j++) = *(arg + i) - 'A' + 'a';
    }

    /* add a null character terminator */
    *(arg + j) = '\0';

}


int str_len(char *arg)
{
    /*return count of letters in a C string */
    int i = 0;
    if ( arg != NULL )
        while ( arg[i] != '\0' )
            i++;
    return i;
}

这是尝试使用数组失败的非工作版本(它编译但在运行时崩溃):

#include <stdio.h>

void toAlpha(char*);
int str_len(char*);
void palindrome(char*);

int main()
{
    char *test_strings[1];                      /* strings to test */
    char *pStr = NULL;                          /* pointer to string */
    int i = 0;                                  /* loop counter */

    test_strings[0] = "TEST1";
    test_strings[1] = "TEST2";

    for (i = 0; i < 1; i++){
        pStr = test_strings[i];
        toAlpha(pStr);
        printf("%s\n", pStr);
    }

    return 0;
}


void toAlpha(char *arg)
{
    int i = 0;                  /* counter - original string*/
    int j = 0;                  /* counter - temp string */

    /* check each character in original and save alphabetic characters only */
    for ( i = 0; i < str_len(arg); i++ )
    {
        if( *(arg + i) >= 'a' && *(arg + i) <= 'z' )
            *(arg + j++) = *(arg + i);
        else
            if ( *(arg + i) >= 'A' && *(arg + i) <= 'Z' )
                *(arg + j++) = *(arg + i) - 'A' + 'a';
    }

    /* add a null character terminator */
    *(arg + j) = '\0';

}


int str_len(char *arg)
{
    /*return count of letters in a C string */
    int i = 0;
    if ( arg != NULL )
        while ( arg[i] != '\0' )
            i++;
    return i;
}

【问题讨论】:

  • 2字undefined behaviour
  • 其他地方可能存在未定义的行为,但这一行:test_strings[1] = "TEST2"; 肯定是未定义的行为。
  • 还有 2 个单词 syntactical sugar -- 即 char foo[] = "......"; 就像您在第一个示例中所做的那样,这是一种特殊的语法糖。详细解释见cmets中第一个SO链接
  • 谢谢。我一直在阅读链接,并在堆栈溢出时在这里找到了一些关于此的其他帖子。会遵守的!语法糖很甜,至少有一段时间。

标签: c


【解决方案1】:

我发现了错误。您不能修改字符串文字。要解决此问题,您需要替换以下内容:

test_strings[0] = "TEST1";
test_strings[1] = "TEST2";

作者:

test_strings[0] = (char *) malloc(sizeof(char) * (strlen("TEST1") + 1)); // +1 for the \n
test_strings[1] = (char *) malloc(sizeof(char) * (strlen("TEST2") + 1)); // +1 for the \n
strcpy(test_strings[0], "TEST1");
strcpy(test_strings[1], "TEST2");

由于您不想包含 string.h,因此您似乎需要实现函数 strcpy。您还需要包含 stdlib.h(因为 malloc)。

【讨论】:

  • 好的。我相信。会试一试。我想我也会分解并添加 string.h - 今晚不再编写我自己的字符串函数!
【解决方案2】:

您必须为 NULL 宏和 printf 包含“stdio.h”。 运行时问题是因为您有一个包含 1 个元素的数组,并且您将“TEST2”分配到不存在的第二个位置。 我不明白你想在 toAlpha() 中做什么。

#include <stdio.h>

// ...

int main()
{
    char *test_strings[2];                      /* strings to test */
    char *pStr = NULL;                          /* pointer to string */

    test_strings[0] = "TEST1";
    test_strings[1] = "TEST2";

    for (int i = 0; i < 2; ++i)
    {
        pStr = test_strings[i];
        toAlpha(pStr);
        printf("%s\n", pStr);
    }

    return 0;
}

// ...

【讨论】:

【解决方案3】:

好的。重写了两个程序。希望这次会更好。但使用 string.h 库代替编写我自己的 strcpy 函数。虽然我没有正确描述 toAlpha。它旨在删除任何非字母字符,并将结果作为所有小写字母返回。 --Topsail

第一个程序(单字符串):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

    void toAlpha(char*);
    int str_len(char*);

    int main()
    {
        char test_string[100];              /* string to test */
        char *pStr = NULL;                  /* pointer to string */

            strcpy(test_string, "Test-A");
            pStr = test_string;
            toAlpha(pStr);
            printf("%s\n", pStr);


        return 0;
    }


    void toAlpha(char *arg)
    {
        int i = 0;                  /* counter - original string*/
        int j = 0;                  /* counter - temp string */

        /* check each character in original and save alphabetic characters only */
        for ( i = 0; i < str_len(arg); i++ )
        {
            if( *(arg + i) >= 'a' && *(arg + i) <= 'z' )
                *(arg + j++) = *(arg + i);
            else
                if ( *(arg + i) >= 'A' && *(arg + i) <= 'Z' )
                    *(arg + j++) = *(arg + i) - 'A' + 'a';
        }

        /* add a null character terminator */
        *(arg + j) = '\0';

    }


    int str_len(char *arg)
    {
        /*return count of letters in a C string */
        int i = 0;
        if ( arg != NULL )
            while ( arg[i] != '\0' )
                i++;
        return i;
    }

带有字符串数组的第二个程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

    void toAlpha(char*);
    int str_len(char*);
    void palindrome(char*);

    int main()
    {
        char *test_strings[2];                      /* strings to test */
        char *pStr = NULL;                          /* pointer to string */
        int i = 0;                                  /* loop counter */

        test_strings[0] = (char *) malloc(sizeof(char) * (strlen("TEST-A") + 1));
        strcpy(test_strings[0], "TEST-A");
        test_strings[1] = (char *) malloc(sizeof(char) * (strlen("TEST-1") + 1));
        strcpy(test_strings[1], "TEST-B");


        for (i = 0; i < 2; i++){
            pStr = test_strings[i];
            toAlpha(pStr);
            printf("%s\n", pStr);
            free(pStr);
        }

        return 0;
    }


    void toAlpha(char *arg)
    {
        int i = 0;                  /* counter - original string*/
        int j = 0;                  /* counter - temp string */

        /* check each character in original and save alphabetic characters only */
        for ( i = 0; i < str_len(arg); i++ )
        {
            if( *(arg + i) >= 'a' && *(arg + i) <= 'z' )
                *(arg + j++) = *(arg + i);
            else
                if ( *(arg + i) >= 'A' && *(arg + i) <= 'Z' )
                    *(arg + j++) = *(arg + i) - 'A' + 'a';
        }

        /* add a null character terminator */
        *(arg + j) = '\0';

    }


    int str_len(char *arg)
    {
        /*return count of letters in a C string */
        int i = 0;
        if ( arg != NULL )
            while ( arg[i] != '\0' )
                i++;
        return i;
    }

【讨论】:

  • 注意:作为练习,实现字符串复制功能并不困难。请参阅此处的注释(和注意事项):stackoverflow.com/questions/5695992/… 以及 Kernighan 和 Ritchie 第 2 版第 5.5 节。
猜你喜欢
  • 1970-01-01
  • 2014-10-18
  • 2020-11-27
  • 1970-01-01
  • 2016-06-19
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2020-07-18
相关资源
最近更新 更多