从字符串中打印一个字符

Mar*_*tin 2 c arrays string io memory-management

我正面临一个与从 c 中的字符串打印一个字符有关的问题。该函数从用户那里获取两个变量 - 数字(应该从字符串打印字符的数字)和字符串。当我将字符串“Martin”放入并且数字为 5 时,输出为“i”。但是当数字大于字符串长度时,就会出现问题,我实际上不知道出了什么问题。

附注。如果数字长于字符串大小,则应打印“Nothing”。

void printLetter() {

    char * string = (char*)malloc(sizeof(char));
    int n;

    printf("Number:\n");
    scanf("%i", &n);
    printf("String:\n");
    scanf("%s", string);

    if(n > strlen(string)) {
        printf("nothing");
    } else {
        printf("%c\n", string[n+1]);
    }

    free(string);


} 
Run Code Online (Sandbox Code Playgroud)

gsa*_*ras 5

这里不需要动态分配,因为你事先不知道字符串的长度,所以只需:

void printLetter() {
    char string[100]; // example size 100
    ...
    scanf("%99s", string); // read no more than your array can hold
}
Run Code Online (Sandbox Code Playgroud)

一个有趣的练习是计算字符串的长度,根据需要动态分配完全相同的空间(+1 表示空终止符),复制string到动态分配的空间,根据需要使用它,然后释放它。


此外这个:

printf("%c\n", string[n+1]);
Run Code Online (Sandbox Code Playgroud)

应该这样写:

printf("%c\n", string[n-1]);
Run Code Online (Sandbox Code Playgroud)

因为您不想超出数组范围(并导致Undefined Behavior),或者在请求的字符的下一个打印两个字符,因为当我要求第一个字符时,您应该打印string[0],当我要求第二个字符时,您应该打印string[1],等等。所以你明白为什么我们需要 print string[n-1],当用户要求输入n-th 个字母时。

顺便说一句,这是通常使用一个命名的变量i,而不是n在你的情况下,有问题时ndex。;)


在你的代码中,这个:

char * string = malloc(sizeof(char));
Run Code Online (Sandbox Code Playgroud)

只为一个字符分配内存,这是不好的,因为即使字符串只有一个字母,你会把空终止符放在哪里?你知道 C 中的字符串应该(几乎)总是NULL终止。

为了为 size 的字符串动态分配内存N,您应该执行以下操作:

char * string = malloc((N + 1) * sizeof(char));
Run Code Online (Sandbox Code Playgroud)

N字符分配空间,为NULL终止符加 1 。