将元素从一个字符数组复制到另一个数组

8

我想把一个字符串中的元素转移到另一个字符串中,因此写了以下程序。最初,我认为for循环应该执行到NULL字符(包括它)被复制为止。但在这个代码中,如果发现了一个NULL字符(即尚未复制),for循环就会终止,但仍能显示已经复制了元素的字符串。如果一开始没有NULL字符,这是如何可能的?

#include<stdio.h>
#include<stdlib.h>

int main()
{
    char temp[100], str[100];
    fgets(str, 100, stdin);
    int i;
    for(i = 0; str[i]!='\0'; i++)
    {
        temp[i] = str[i];
    }
    puts(temp);
    return 0;
}

3
“NULL”是一个带有“空指针常量”的宏。这里并不相关。你所指的是ASCII编码中整数值为0的字符“NUL”或“nul”。 - too honest for this site
阅读有关 strcpy 的内容。 - Pete Becker
1
@Pete Becker 我认为这很可能是一道类似于家庭作业/教程问题(即旨在使人们意识到复制字符串的问题)的题目。仅仅告诉某人阅读有关 strcpy 的内容并不能帮助他们理解这个问题。 - Tersosauros
1
@Tersosauros - 初学者经常自己编写函数,因为他们不知道标准库中有什么。 - Pete Becker
1
@Tersosauros - 是的,这就是为什么我的评论是一个“评论”,而不是一个“答案”。 - Pete Becker
显示剩余3条评论
3个回答

7

void puts(const char *)函数依赖于size_t strlen(const char *),当传递的参数中没有空终止符时(请参见此答案),该函数的输出是未定义的。因此,在您的情况下,puts内部的strlen可能会在内存中的数组旁边找到0值,从而导致puts的正确行为,但这并不总是发生,因为它是未定义的。


7
以下是我电脑上的输入和输出内容:
0
0
絯忐`

Process returned 0 (0x0)   execution time : 1.863 s
Press any key to continue.

看到那个“絯忐`”废品了吗? 这是未定义的行为。 你的程序能够正常工作,因为你很 (不)幸运

再次强调,未定义的行为并不值得 过多 讨论。


3
我本来要点赞的,直到我看到最后一行:“未定义的行为不值得讨论。”虽然OP像你所说的那样“(不)幸运”,但我认为不讨论这种未定义的行为就是没有正确回答问题。 - Tersosauros
1
当未定义的行为发生时,任何事情都可能发生。正如K&R所指出的那样,“如果您不知道它们在各种机器上是如何完成的,那么这种无知可能有助于保护您。”因此,我认为最好不要讨论未定义的行为。 - nalzok

3
当你声明char temp[100]而没有对其进行任何初始化时,它只是占用未初始化的内存。这个内存可以是任何值。例如,下面的程序将写出它的初始内容,作为整数:
#include<stdio.h>
#include<stdlib.h>

int main()
{
    char temp[100];
    int i;
    for(i = 0; i < 100 ; i++)
    {
        fprintf(stdout, "%d ", temp[i]);
    }
    return 0;
}

这个程序对我来说输出结果始终不同,尽管偶然会打印一些零的部分。例如:
88 -70 43 81 -1 127 0 0 88 -70 43 81 -1 127 0 0 1 0 0 0 0 0 0 0 112 -70 43 81 -1 127 0 0 0 64 -108 14 1 0 0 0 72 50 -13 110 -1 127 0 0 -128 -70 43 81 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 -70 43 81
88 90 72 88 -1 127 0 0 88 90 72 88 -1 127 0 0 1 0 0 0 0 0 0 0 112 90 72 88 -1 127 0 0 0 -96 119 7 1 0 0 0 72 18 72 105 -1 127 0 0 -128 90 72 88 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 90 72 88
88 -6 -79 87 -1 127 0 0 88 -6 -79 87 -1 127 0 0 1 0 0 0 0 0 0 0 112 -6 -79 87 -1 127 0 0 0 0 14 8 1 0 0 0 72 34 57 104 -1 127 0 0 -128 -6 -79 87 -1 127 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 96 -6 -79 87
最有可能发生的情况是,由于 temp [strlen(str)] 值恰好为\0,您的非空终止字符串意外地被终止了。

1
打印这些变量是未定义行为。 - Giorgi Moniava
@Giorgi 怎么了?据我所知,规定我得到100个字节,但这些字节的值是未定义的。它们应该可以安全地打印,但从来没有保证它们是什么。 - yaakov
2
请阅读未定义行为的概念。读取未初始化的变量属于UB。 - Giorgi Moniava
1
char temp[100]; 是一个 char 数组。使用 char 的格式说明符来打印它们:fprintf(stdout, "%c ", temp[i]);d 格式说明符想要读取 4 个字节。c 格式说明符只读取 1 个字节。 - ryyker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接