【问题标题】:Printing a String ( character pointer ) using Printf directly - Weird behaviour直接使用 Printf 打印字符串(字符指针) - 奇怪的行为
【发布时间】:2020-08-28 01:51:18
【问题描述】:

在以下 c 代码中,删除 ln8 和 lb9 后,“第 10 行”不打印任何内容。它只接受输入并且不打印任何内容。但奇怪的是添加了这两行,代码工作得非常好,即输入字符串被 for 循环打印两次,一次被 ln10 中的 printf 语句打印。 (我想做的只是打印输入字符串) 我使用 MinGw 编译器并使用 cmd 运行代码。enter image description here

int main()
{
 char *s;
 scanf("%s",s);

 printf("Line 9:\t");
 for(int i=0;s[i]!='\0';i++) //line 8

 printf("%c",*(s+i)); //line 9

 printf("\nLine 12:\t%s\n",s); //line10
 return 0;
}

【问题讨论】:

  • 这确实是一个有趣的问题,但不是 c 语言。你看char *s; 声明了一个指向内存位置的指针。但是由于您没有对其进行初始化,因此指针未定义。所以它指出谁知道内存在哪里。而scanf 会将字符串存储在那里,但由于谁知道它在哪里不受更改保护,所以它可能会在操作之间发生变化。这一切都归结为:您使用了一个 uninitialized 变量,这会导致未定义的行为。这意味着任何更改(重新编译、在另一台机器上执行……)都会导致不同的行为。
  • 请注意,编译时始终使用标志-Wall,它会告诉您使用了未初始化的变量。
  • 谢谢!它给了我一个警告,即 s 在 scanf 中未初始化。

标签: c string for-loop printf scanf


【解决方案1】:
char *s

您声明了一个指针,但没有为它分配。它是未定义的。因为未定义的行为,一切都可能发生。 (例如,当我在我的 PC 中测试你的程序时,它会引发 Segmentation fault (core dumped)

你必须在scanf之前为指针分配(不要忘记释放s):

char *s = malloc(sizeof(char) * MAX_LEN); // MAX_LEN: you define its value.

或者你可以使用字符数组:

char s[100]; // here, the string length is up to 99;

【讨论】:

    【解决方案2】:

    尝试使用 strdup 初始化 s。

    int main()
    {
     char *s = strdup("");
     scanf("%s",s);
    
     printf("\nLine 12:\t%s\n",s); //line10
     return 0;
    }
    

    【讨论】:

    • 现在 s 指向一个只有 1 个字符的空字符串。这可能还不够。
    • 我测试过了。它适用于此。您也可以尝试测试一下吗。
    • 这是因为内存分配器可能分配了不止一个字符,所以错误并不明显。但错误永远不会少。
    • 尝试使用"thisisaverylongstringthatshouldcauseanerrorbecauseIdidnotreadmylecturenotesonstrings"进行测试
    • 刚刚在我的程序和它的工作上测试了它。我还添加了更多字符。它仍然有效。顺便说一句,我正在使用 vs2017 进行测试。问题是char *s的初始化,我刚才提到了一种方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 1970-01-01
    相关资源
    最近更新 更多