如何在C中正确输入字符串
我目前正在学习C,所以我想创建一个程序,要求用户输入一个字符串并输出输入的字符数,代码编译得很好,当我只输入1个字符就可以了,但是当我输入2个或更多字符,无论我输入的字符数是多少,它总会说只有一个字符然后崩溃。 这是我的代码,我无法弄清楚出了什么问题。
int main(void) { int siz; char i[] = ""; printf("Enter a string.\n"); scanf("%s", i); siz = sizeof(i)/sizeof(char); printf("%d", siz); getch(); return 0; }
我目前正在学习编程,所以如果有办法使用相同的scanf()函数,我会很感激,因为我还没有学会如何使用任何其他函数,可能无法理解它是如何工作的。
请忘记scanf
存在。 你遇到的问题,虽然主要是由你可以理解的缺乏经验造成的,但即使你有经验,也会继续困扰你 – 直到你停下来。
原因如下:
scanf
将读取输入,并将结果放入您提供的char
缓冲区中。 但是,它不会检查以确保有足够的空间。 如果它需要的空间超过您提供的空间,它将覆盖其他内存位置 – 通常会带来灾难性的后果。
一个更安全的方法使用fgets
– 这是一个与scanf
大致相同的函数,但它只会读入为您创建空间的多个字符(或者:如您所说 ,为其创建空间)。
其他观察: sizeof
只能评估编译时已知的大小:基本类型(int,double等)占用的字节数或固定数组的大小(如int i [100];)。 它不能用于确定程序期间的大小(如果“大小”是一个改变的东西)。
你的程序看起来像这样:
#include #include #define BUFLEN 100 // your buffer length int main(void) // <<< for correctness, include 'void' { int siz; char i[BUFLEN]; // <<< now you have space for a 99 character string plus the '\0' printf("Enter a string.\n"); fgets(i, BUFLEN, stdin); // read the input, copy the first BUFLEN characters to i siz = sizeof(i)/sizeof(char); // it turns out that this will give you the answer BUFLEN // probably not what you wanted. 'sizeof' gives size of array in // this case, not size of string // also not siz = strlen(i) - 1; // strlen is a function that is declared in string.h // it produces the string length // subtract 1 if you don't want to count \n printf("The string length is %d\n", siz); // don't just print the number, say what it is // and end with a newline: \n printf("hit to exit program\n"); // tell user what to do next! getc(stdin); return 0; }
我希望这有帮助。
更新你问了合理的后续问题:“我怎么知道字符串太长”。
请参阅此代码段以获取灵感:
#include #include #define N 50 int main(void) { char a[N]; char *b; printf("enter a string:\n"); b = fgets(a, N, stdin); if(b == NULL) { printf("an error occurred reading input!\n"); // can't think how this would happen... return 0; } if (strlen(a) == N-1 && a[N-2] != '\n') { // used all space, didn't get to end of line printf("string is too long!\n"); } else { printf("The string is %s which is %d characters long\n", a, strlen(a)-1); // all went according to plan } }
请记住,当你有N个字符的空格时,最后一个字符(在位置N-1
)必须是'\0'
并且由于fgets
包含'\n'
,你输入的最大字符串实际上是N-2
字符长。
这一行:
char i[] = "";
相当于:
char i[1] = {'\0'};
数组i
只有一个元素,程序因缓冲区溢出而崩溃。
我建议你使用fgets()
替换scanf()
如下所示:
#include #define MAX_LEN 1024 int main(void) { char line[MAX_LEN]; if (fgets(line, sizeof(line), stdin) != NULL) printf("%zu\n", strlen(line) - 1); return 0; }
长度减1
因为fgets()
会在末尾存储新行字符。
问题出在这里:
char i[] = "";
您实际上是创建一个大小为1的char array
,因为它设置为等于""
;
而是使用更大尺寸的缓冲区:
char i[128]; /* You can also malloc space if you desire. */ scanf("%s", i);
如果要在输入字符串中包含空格,请参阅下面的链接以查找类似的问题。 关于scanf
替代方案,还有一些很好的输入。
如何使用scanf输入空格?
那是因为char i[] = "";
实际上是一个单元素数组。
C中的字符串存储为以\0
(值为0的char
)结尾的文本。 你应该使用更大的缓冲区,例如:
char i[100]; scanf("%s", i);
然后,在计算此字符串的长度时,您需要搜索\0
char。
int length = 0; while (i[length] != '\0') { length++; }
运行此代码后, length
包含指定输入的长度。
您需要在放置输入数据的位置分配空间。 在您的程序中,您可以分配空间,如:
char i[] = " ";
哪个会好的。 但是,使用malloc
更好。 查看手册页。