将字符串保存为数组并在C中打印出来

时间:2018-12-01 12:30:15

标签: c arrays

希望大家都做得很好!

这是我要尝试的操作-我想创建一个程序,该程序将最多包含50个符号(或更少)的字符串保存到数组中,然后打印出每个数组符号。问题是C中没有像.append这样的方法。如果我不知道字符串的确切长度,如何解决此问题?

任何示例或建议都非常受欢迎。 P.s.我是C编程的新手(以前使用过Java,JavaScript等),所以请忍受:)

3 个答案:

答案 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]);
    }
}

终于安全了。松一口气!