希望大家都做得很好!
这是我要尝试的操作-我想创建一个程序,该程序将最多包含50个符号(或更少)的字符串保存到数组中,然后打印出每个数组符号。问题是C中没有像.append这样的方法。如果我不知道字符串的确切长度,如何解决此问题?
任何示例或建议都非常受欢迎。 P.s.我是C编程的新手(以前使用过Java,JavaScript等),所以请忍受:)
答案 0 :(得分:1)
wizwizz4的答案中关于'\0'
的想法帮助我解决了这个问题。但是,我用另一种方式做到了:
#include <stdio.h>
int main(){
char input[50];
printf("%s\n","Enter The String:");
fgets(input,sizeof(input),stdin);
for(int i=0; input[i]!='\0'; i++){
printf("%c",input[i]);
}
}
效果很好,很短。如果我们排除打印的字符串本身没有'\0'
,这是一种很好的安全方法。
答案 1 :(得分:0)
我建议您始终将字符串的长度保留在变量中。另外,您可以使用函数strlen()
。
大多数与字符串相关的函数在<string.h>
中都有一个原型。您需要包括该标准标题。
#include <string.h>
char text[51] = {0};
int textlen = 0; // should be size_t
// possibly, in other lang: text = "foobar"
strcpy(text, "foobar");
textlen = strlen(text); // 6 in this easy case
// possibly, in other lang: text = text + character
if (textlen < 50) {
text[textlen++] = character; // add character to text, update textlen
text[textlen] = '\0'; // remember the terminator
} else {
fprintf(stderr, "not enough space for all characters.\n");
exit(EXIT_FAILURE);
}
例如,在c-faq的第8章中了解有关字符串的信息
答案 2 :(得分:-1)
为了解决此问题,我们需要知道C字符串实际上是什么。幸运的是,我已经知道,所以我可以告诉你。
C字符串是不是'\0'
的字符序列,后跟'\0'
字符。它可以是任何长度。当我们传递字符串时,(几乎)总是绕着指针指向字符串的第一个字符(即,它在内存中的存储位置)。使用字符串时,请继续进行直到看到'\0'
。如您所见,这使得真正容易意外地引入了安全漏洞。
现在,我们如何使用字符串? C标准库在这里可以节省一天!
#include <string.h>
这条神奇的线意味着您现在可以使用诸如strcpy
之类的功能!
#include <string.h>
#include <stdio.h>
char array[50];
int main(int argc, char *argv[]) {
if (argc < 2) return 1; // Exit early if we don't have an argument.
strcpy(array, argv[1]); // Copy first argument
for (size_t i = 0; i < 50; i += 1) {
printf("%c", array[i]);
}
}
看,它有效:
wizzwizz4@myLaptop:~$ ./a.out "Hello this is my string!"
Hello this is my string!^@k£"'l`¬.v'4ka36}'3.^D,2#xf
但是...您可能会发现错误。如果字符串比空格长 怎么办?
wizzwizz4@myLaptop:~$ ./a.out "Hello this is my string that is too long padding... k'57M3'ck~^B345"
Hello this is my string that is too long padding..
I, THE MIGHTY ATTACKER, HAVE OVERWRITTEN PARTS OF MEMORY THAT I SHOULD NEVER HAVE HAD ACCESS TO AND NOW CONTROL YOUR COMPUTER!
糟糕,array
之后的内存空间恰好包含一些代码,当攻击者告诉我们的程序用k'57M3'ck~^B345
覆盖该代码时,攻击者就可以进入了!要解决此问题,请改用strncpy
:
#include <string.h>
#include <stdio.h>
char array[50];
int main(int argc, char *argv[]) {
if (argc < 2) return 1; // Exit early if we don't have an argument.
strncpy(array, argv[1], 49); // Copy first argument
for (size_t i = 0; i < 50; i += 1) {
printf("%c", array[i]);
}
}
运行它!
wizzwizz4@myLaptop:~$ ./a.out "Hello this is my string that is too long padding... k'57M3'ck~^B345"
Hello this is my string that is too long padding..f
成功!除了...这个“字符串”不是以'\0'
结尾–并不是真正的字符串。这意味着如果您尝试将array
的内容视为字符串,该程序将崩溃,因为使用该字符串的任何内容都会读取和读取其他内存位,直到找到'\0'
或崩溃为止,例如所以:
#include <string.h>
#include <stdio.h>
char array[50];
int main(int argc, char *argv[]) {
if (argc < 2) return 1; // Exit early if we don't have an argument.
strncpy(array, argv[1], 49); // Copy first argument
printf("%s", array); // Uh oh...
}
运行它...
wizzwizz4@myLaptop:~$ ./a.out "Hello this is my string that is too long padding... k'57M3'ck~^B345"
Hello this is my string that is too long padding..f^D^D^D^D'2mCln My Password is 358231
^F^JESegmentation fault (core dumped)
要解决此问题,我们需要添加最后一个'\0'
:
#include <string.h>
#include <stdio.h>
char array[50];
int main(int argc, char *argv[]) {
if (argc < 2) return 1; // Exit early if we don't have an argument.
strncpy(array, argv[1], 49); // Copy first argument
array[49] = '\0';
for (size_t i = 0; i < 50; i += 1) {
printf("%c", array[i]);
}
}
终于安全了。松一口气!