您的变量char **global;
是灾区。它是一个空指针。必须先指向一些有效数据,然后才能使用它。事实上,它是一个双指针,所以你必须像这样提供空间:
char array[1000];
char *pointer = array;
char **global = &pointer;
现在您可以安全地使用global[0]
.
在函数内部,您传递&global
给scanf()
; 那是一个char ***
。成为“三星级程序员”并不是一件好事,尤其是当您是偶然而不是设计时这样做的。
您包含标题<string.h>
但不使用它的任何功能。你确实使用了函数<stdio.h>
,但你没有包含它。printf()
从技术上讲,您通过使用可变参数函数并且scanf()
在范围内没有函数原型来调用未定义的行为。编译器有权被告知接受可变数量参数的函数(这就是“可变参数”的意思),并且有权在没有被告知该函数是可变参数的情况下错误编译代码。
假设您确实确实需要一个全局变量(它们通常不是一个好主意,您应该尽可能避免使用它们),那么您可以合理地编写:
#include <stdio.h>
char global[1000];
int main(void)
{
printf("Please Enter Text: ");
if (scanf("%s", global) == 1)
printf("%s\n", global);
return 0;
}
这至少是合理的代码,但它仍然存在您原来的问题,它只能读取一个单词,而不是整行。
忘记它的gets()
存在。它是 1988 年第一个 Internet 蠕虫(谷歌为“莫里斯 Internet 蠕虫”)中使用的错误功能之一。这是无法挽回的;它不能在恶劣的环境中安全使用,并且所有编程都必须在恶劣的环境中完成。
要读取一行,请使用fgets()
.
#include <stdio.h>
#include <string.h>
char global[1000];
int main(void)
{
printf("Please Enter Text: ");
if (fgets(global, sizeof(global), stdin) != NULL)
{
size_t len = strlen(global);
if (len != 0 && global[len-1] == '\n')
global[--len] = '\0';
printf("%s\n", global);
}
return 0;
}
这会将一行数据放入global
.
你可以合法地问怎么len
可能是零(我问自己,我assert(len != 0)
因为答案而替换了)。一个答案是“标准输入是从二进制文件重定向的,第一个字节是空(零)字节”。然后fgets()
将读取包括空字节的数据,直到第一个换行符,但strlen()
将在空字节处停止,并将长度报告为 0。
代码从字符串中删除换行符,同时确定它的长度——你通常需要那个长度。然后打印它。请注意,代码检查fgets()
成功。I/O(尤其是输入)有在你不看的时候打破的习惯。很多时候,它会工作得很好,但是为了让你的程序健壮,你必须对输入操作失败(以及后来的内存分配失败)保持偏执。