C语言 我想知道为什么输出此结果

fdbelqdn  于 2023-02-15  发布在  其他
关注(0)|答案(2)|浏览(85)
源代码
/***************************************************
 * Copyright: 2023, 黄子涵.
 * File name: huangzihan_c_program_142
 * Description: 改变指针的值
 * Author: 黄子涵
 * Version: V1.0.0
 * Date: 2023-01-08
 * ****************************************************/

#include <stdio.h>

char huangzihan[10];
char huangchunqin[12];
char chenlanying[12];
char shejiazi[8];
void name_input();
void name_output();
void name_output_n();

void name_input()
{
    int i;
    printf("*********************************\n");
    printf("     给字符数组输入对应的名字    \n");
    printf("*********************************\n");
    printf("请输入黄子涵的小写拼音:");
    for (i = 0; i < 10; i++)
    {
        scanf("%c", &huangzihan[i]);
        if (huangzihan[i] == 10)
        {
            huangzihan[i] = '\0';
            break;
        }
    }
    getchar();
    printf("请输入黄春钦的小写拼音:");
    for (i = 0; i < 12; i++)
    {
        scanf("%c", &huangchunqin[i]);
        if (huangchunqin[i] == 10)
        {
            huangchunqin[i] = '\0';
            break;
        }
    }
    getchar();
    printf("请输入陈兰英的小写拼音:");
    for (i = 0; i < 11; i++)
    {
        scanf("%c", &chenlanying[i]);
        if (chenlanying[i] == 10)
        {
            chenlanying[i] = '\0';
            break;
        }
    }
    getchar();
    printf("请输入佘佳梓的小写拼音:");
    for (i = 0; i < 8; i++)
    {
        scanf("%c", &shejiazi[i]);
        if (shejiazi[i] == 10)
        {
            shejiazi[i] = '\0';
            break;
        }
    }
    printf("\n");
}

void name_output()
{
    char *p1,*p2,*p3,*p4;
    printf("*********************************\n");
    printf("     将字符数组对应的名字输出    \n");
    printf("*********************************\n");
    printf("输出huangzihan:");
    p1 = huangzihan;
    printf("%s", p1);
    printf("\n");
    printf("输出huangchunqin:");
    p2 = huangchunqin;
    printf("%s", p2);
    printf("\n");
    printf("输出chenlanying:");
    p3 = chenlanying;
    printf("%s", p3);
    printf("\n");
    printf("输出shejiazi:");
    p4 = shejiazi;
    printf("%s", p4);
    printf("\n");
}

void name_output_n()
{
    int i;
    char *p;
    printf("\n");
    printf("*********************************\n");
    printf("           改变指针的值          \n");
    printf("*********************************\n");
    printf("你要从第几个字符输出huangzihan(共10个字符)?");
    scanf("%d", &i);
    p = huangzihan + i - 1;
    printf("这是你要输出的字符串:%s", p);
    printf("\n");
    printf("你要从第几个字符输出huangchunqin(共12个字符)?");
    scanf("%d", &i);
    p = huangchunqin + i - 1;
    printf("这是你要输出的字符串:%s", p);
    printf("\n");
    printf("你要从第几个输出chenlanying(共11个字符)?");
    scanf("%d", &i);
    p = chenlanying + i - 1;
    printf("这是你要输出的字符串:%s", p);
    printf("\n");
    printf("你要从第几个输出shejiazi(共8个字符)?");
    scanf("%d", &i);
    p = shejiazi + i - 1;
    printf("这是你要输出的字符串:%s", p);
    printf("\n");
}

int main()
{
    extern char huangzihan[10];
    extern char huangchunqin[12];
    extern char chenlanying[12];
    extern char shejiazi[8];
    name_input();
    name_output();
    name_output_n();
    return 0;
}

一开始以为是没有添加字符串的结束标记的问题,但添加了字符串的结束标记后发现不起作用,添加代码如下:

if (shejiazi[i] == 10) {
        shejiazi[i] = '\0';
        break;
    }
我要输出结果
输出huangzihan:huangzihan
输出huangchunqin:huangchunqin
输出chenlanying:chenlanying
输出shejiazi:shejiazi
实际输出结果

我想知道为什么会这样,如果你知道,请告诉我,非常感谢。

vof42yt1

vof42yt11#

如果输入字符串正好具有最大字符数,则目标数组不是以null结尾的,从而导致printf("...%s", ...)具有未定义的行为。如果您的情况是数组huangchunqinchenlanying在内存中相邻,则printf("%s",p2);输出huangchunqin的内容,直到找到null终止符为止,而null终止符不会出现在chenlanying结尾之前。
您应该将数组的长度增加一个字节,并使用函数读取这些字符串:

/* Author: 查理戈登 */
/* Description: 程序的修改版本 */

#include <stdio.h>

char huangzihan[11];
char huangchunqin[13];
char chenlanying[13];
char shejiazi[9];

// read a string into a char array of a given length,
// return EOF if no input at end of file, 1 if truncated, 0 otherwise
int input_string(const char *prompt, char *dest, size_t size) {
    size_t i = 0;
    int c;
    int result = 0;

    printf("%s: ", prompt);
    while ((c = getchar()) != EOF && c != '\n') {
        if (i + 1 < size) {
            dest[i++] = c;
        } else {
            result = 1;
        }
    }
    dest[i] = '\0';
    if (i == 0 && c == EOF)
        result = EOF;
    return result;
}

void name_input(void) {
   printf("*********************************\n");
   printf("     给字符数组输入对应的名字    \n");
   printf("*********************************\n");
   // Qǐng shūrù shéjiāzǐ de xiǎoxiě pīnyīn
   input_string("请输入黄子涵的小写拼音", huangzihan, sizeof huangzihan);
   input_string("请输入黄春钦的小写拼音", huangchunqin, sizeof huangchunqin);
   input_string("请输入陈兰英的小写拼音", chenlanying, sizeof chenlanying);
   input_string("请输入佘佳梓的小写拼音", shejiazi, sizeof shejiazi);
   printf("\n");
}
ybzsozfc

ybzsozfc2#

name_input()中,由于最后一次迭代是i=9,所以没有正确终止字符串:

for(i=0;i<10;i++) {
        scanf("%c",&huangzihan[i]);
        if(huangzihan[i]==10)
        {
            huangzihan[i]='\0';
            break;
        }
    }

相反,您可以:

int i = 0;
    for(; i < sizeof huangzihan - 1; i++) {
        scanf("%c", &huangzihan[i]);
    }
    huangzihan[i] = '\0';

我不知道你输入的字母是否适合char,如果不适合,你会得到一些奇怪的腐败。
你也可以只读一个字符串:

#define huangzihan_len 9
#define str(s) str2(s)
#define str2(s) #s
char huangzihan[huangzihan_len+1];

//...

    scanf("%" str(huangzihan_len) "s", huangzihan);

阅读一个字符串后,执行getchar()可能是为了去掉换行符,你可以用一个空格来改变字符串的格式,使其自动“%c”,或者创建一个flush函数,丢弃所有数据,直到你碰到一个新行:

void flush() {
   for(;;) {
       int ch = getchar();
       if(ch == EOF || ch == '\n') return;
   }
}

你的代码是重复的,所以考虑使用数组来保存你的字符串,因为它们的长度不同,也许是一个字符串指针数组char *str[4]

相关问题