【问题标题】:How to Print out an unknown size of string array in C?如何在C中打印出未知大小的字符串数组?
【发布时间】:2016-06-26 13:24:54
【问题描述】:

我想打印一个大小未知的字符串数组,例如 {"Green", "Yellow", "Black", "White", "Purple", "Saphire", .....} 并且可能没有 NULL 结尾。 我的代码如下:((char **) 必须是 PrintStringArray 的参数)

void PrintStringArray(char **list) {
    int i = 0;

    for (;; i++) {
        char *p = list[i];
        while (*p)
                putchar((*p++));
        putchar('\n');
    }
}

void main()
{
    char *list[] = {"Green", "Yellow", "Black", "White", "Purple", "Saphire"};
    PrintStringArray(list);
    return;
}

但结果是,
绿色
黄色
黑色
白色
紫色
蓝宝石
分段错误(核心转储)
如何避免分段错误? 我可以要你的 cmets 吗? 谢谢,

【问题讨论】:

  • 你不能那样做。您必须单独传递大小。
  • 你不能。要么需要将数组长度传递给函数,要么数组必须具有终止标记值(正如您正确提到的那样)。
  • 或者有一个结束标记,比如"FIN"/"END"...
  • 好吧,你可以。毕竟,您示例中的列表是不变的。想想 int numStrings = sizeof(list)/sizeof (list[0]); - 这将为您提供数组中元素的数量。
  • @tofro:这是不正确的,PrintStringArray 没有收到带有任何此类类型信息的 list。为什么不亲自尝试一下?

标签: arrays c pointers c-strings function-definition


【解决方案1】:

无论是指向单个对象还是指向数组的第一个元素,指针都不会保留信息。

考虑下面的代码sn-p

char *p;

char c = 'A';

p = &c;

putchar( *p );

char s[] = "ABC";

p = s;

putchar( *p );

因此,您必须为自己提供有关指针是否指向数组元素的信息。

您可以通过两种方式做到这一点。第一个是指定序列中第一个元素被指针指向的元素的数量。或者序列必须像字符串一样具有标记值。

例如

int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

for ( int *p = a; p < a + sizeof( a ) / sizeof( *a ); ++p )
                          ^^^^^^^^^^^^^^^^^^^^^^^^^^
{
    printf( "%d ", *p );
}
printf( "\n" );

或者

int a[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };

int *p = a;

do
{
    printf( "%d ", *p );
} while ( *p++ != 0 );
          ^^^^^^^^^

printf( "\n" );

这些代码sn-ps可以写成函数

void f( int a[], size_t n ) 
{
    for ( int *p = a; p < a + n; ++p )
    {
        printf( "%d ", *p );
    }
    printf( "\n" );
}

或者

void f( int a[] )
{
    int *p = a;

    do
    {
        printf( "%d ", *p );
    } while ( *p++ != 0 );

    printf( "\n" );
}

打印字符串数组的方式相同。您将自己明确报告数组中的元素数量。或者,您可以使用标记值,例如空指针或空字符串。

例如

#include <stdio.h>

void PrintStringArray( char *s[], size_t n ) 
{
    for ( char **p = s; p < s + n; ++p )
    {
        puts( *p );
    }
    printf( "\n" );
}

int main( void )
^^^^^^^^^^^^^^^^
{
    char *list[] =
    { 
        "Green", "Yellow", "Black", "White", "Purple", "Saphire" 
    };

    PrintStringArray( list, sizeof( list ) / sizeof( *list ) );

    return 0;
}

或者

#include <stdio.h>

void PrintStringArray( char *s[] ) 
{
    char **p = s;

    while ( *p != NULL )
    {
        puts( *p++ );
    }     

    printf( "\n" );
}

int main( void )
^^^^^^^^^^^^^^^^
{
    char *list[] =
    { 
        "Green", "Yellow", "Black", "White", "Purple", "Saphire", NULL
                                                                  ^^^^  
    };

    PrintStringArray( list );

    return 0;
}

【讨论】:

    【解决方案2】:

    为避免分段错误,只需将函数更改为具有size_t 类型的第二个参数即可让您确切知道要处理多少个字符串。检查以下代码:

    #include <stdio.h>
    
    void PrintStringArray(char **list , size_t size);
    
    int main()
    {
        char *list[6] = { "Green", "Yellow", "Black", "White", "Purple", "Saphire" };
        PrintStringArray(list, 6);
        return 0;
    }
    
    void PrintStringArray(char **list, size_t size) {
        size_t i;
    
        for (i = 0; i < size; i++) {
            char *p = list[i];
            while (*p)
                putchar((*p++));
            putchar('\n');
        }
    }
    

    【讨论】:

      【解决方案3】:

      你不能:语言不支持这个。

      程序员通常会做以下两件事之一:

      1. 在传递数组时显式传递大小。

      2. 使用表示数组结束的元素值。在这种情况下,\0 作为数组元素可能适合您。

      【讨论】:

      • 你很好。查看对问题的评论
      • @tofro:是什么让您认为PrintStringArray 收到了list,而sizeof 的信息可以通过您引用的方式获得?你错了。
      • @Bathsheba:我把 NULL 作为结尾,{"Green", "Yellow", "Black", "White", "Purple", "Saphire", NULL}。同时修改代码为:while (*p != NULL) putchar((*p++));然后我像往常一样遇到了分段错误。
      猜你喜欢
      • 2023-03-07
      • 2022-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多