【问题标题】:c, why i can't print all elements of my arrayc,为什么我不能打印我的数组的所有元素
【发布时间】:2022-09-28 14:52:53
【问题描述】:

我正在用c编写一个简单的程序,打印数组的所有元素。数组是

char op[2][50] = {\"option1\", \"option2\"};

该程序是

int main(int argc, char * argv[])
{
    char spaces[6] = \"      \";
    int choice;
    char op[2][50] = {\"option1\", \"option2\"};

    printf(\"\\n\\n\\t=========== OPTIONS ===========\\n\\n\\t\");
    for (int i;i<sizeof(op)/sizeof(op[0]);i++) {printf(\"%s[%d]: %s\\n\\t\",spaces,i+1,op[i]);}
    printf(\"\\n\\t\\t%s[?]: \",spaces);
    scanf(\"%d\",&choice);
    
    if (choice==1) {firstFunction();} //i\'ve declared this function, but here isn\'t important

    return 0;
}

所以,问题是选项未打印. 输出:

=========== VIDEO TOOLS ===========


               [?]:

问题本质上是 if 语句,因为我尝试在上面和下面添加其他 printf 并且它们可以工作。此外,该 if 语句在对程序进行一些更改之前起作用,所以问题可能是其他代码行(?)

我是 c 的初学者,所以请不要暴露复杂的解决方案。谢谢

  • i 的值是多少?
  • spaces 的大小太小,无法容纳您希望它容纳的字符串。请记住,C 中的字符串确实被称为空终止字符串。这意味着一个六个字符的字符串确实需要七个空间,才能容纳终止符。删除spaces 的尺寸规格以解决该问题:char spaces[] = \" \";
  • 让它成为一种习惯结尾您的 printf 行与 \\n 而不是从它们开始。因为\\n 不仅改变了行,它还可能刷新某些系统上的标准输出。未能刷新标准输出可能会导致输出以奇怪的顺序出现或丢失。
  • i\'m a beginner with c... 那你还有时间不习惯使用(并且浪费时间去追逐使用带来的问题)scanf( )快跑!弄清楚如何使用fgets() 并处理它可以提供的“一次一行”输入。不要偷懒...因为scanf()的滥用和误用导致的SO问题太多...不推荐...
  • @Fe2O3 我试过 fgets!但我有一个问题.. 如果我使用两个连续的 fget,第一个 fget 不起作用.. 你知道我该如何解决吗?

标签: arrays c for-loop initialization string-literals


【解决方案1】:

很多错误。 cmets中提到的东西总结:

  • i 在未初始化时使用,将其设置为零。

  • char spaces[6] = " "; 太小,请参阅 How should character arrays be used as strings?

  • 让它成为一种习惯结尾您的 printf 行与 \n 而不是从它们开始。因为\n 不仅改变了行,它还可能刷新某些系统上的标准输出。未能刷新标准输出可能会导致输出以奇怪的顺序出现或丢失。

此外,如果这些是只读字符串,则考虑使用一维指针数组,因为这样更灵活且内存效率更高:

const char* op[2] = {"option1", "option2"};

【讨论】:

  • 很高兴指出“指定 6”是一个糟糕的举动。最好让编译器测量事物。但是,然后,将指针数组的大小设置为2 并向编译器指示该维度???奇怪的...
【解决方案2】:

for (int i;i&lt;sizeof(op)/sizeof(op[0]);i++)

您没有初始化 i 变量,它是一个未定义的行为 (UB)

它应该是:

for (int i = 0;i<sizeof(op)/sizeof(op[0]);i++)

或更好(使用正确的大小和正索引类型)

for (size_t i = 0;i<sizeof(op)/sizeof(op[0]);i++)

要打印size_t,请使用%zu 格式

另外,请记住 C 字符串由空终止字符终止。因此,您需要添加比字符串文字中看到的多一个字符。 (“123”需要 4 个字符)spaces 数组太短,无法容纳 " "char spaces[] = " ";

【讨论】:

    【解决方案3】:

    显式指定元素数量的此数组声明:

    char spaces[6] = "      ";
    

    容易出错。该数组不包含字符串,因为用作初始值设定项的字符串文字的终止零字符'\0' 未存储在数组spaces 中。字符串文字的大小等于7 而不是6

    所以写起来更安全:

    char spaces[] = "      ";
    

    或者因为您不打算更改数组,所以最好写:

    const char *spaces = "      ";
    

    在这个二维数组的声明中:

    char op[2][50] = {"option1", "option2"};
    

    您明确指定该数组包含两个元素。所以使用表达式i&lt;sizeof(op)/sizeof(op[0]) 没有多大意义。

    在数组声明之前引入一个命名常量,例如:

    enum { N = 2 };
    char op[N][50] = {"option1", "option2"};
    

    然后使用表达式:

    i < N
    

    在 for 循环中。或者像这样声明数组:

    char op[][50] = {"option1", "option2"};
    

    并在声明之后引入一个命名常量,如:

    const size_t N = sizeof( op )/sizeof( op[0] );
    

    并在 for 循环中使用常量,顺便说一下您忘记初始化变量 i

    for ( size_t i = 0; i < N; i++ ) 
    {
        printf("%s[%zu]: %s\n\t",spaces,i+1,op[i]);
    }
    

    由于变量 i 现在具有 size_t 类型,因此您必须在调用 printf 时使用转换说明符 %zu 而不是 %d

    重写这段代码会更安全 sn -p

    scanf("%d",&choice);
    
    if (choice==1) {firstFunction();} // I've declared this function, but here isn't important
    

    以下方式:

    if ( scanf("%d",&choice) == 1 && choice==1 ) 
    {
        firstFunction();
    } // I've declared this function, but here isn't important
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-21
      • 1970-01-01
      相关资源
      最近更新 更多