劳尔的狙击镜 2024-01-22 21:02 采纳率: 100%
浏览 12
已结题

c++,两个地址连续的字符串输出问题

c++程序代码:

#include<bits/stdc++.h>
using namespace std;
struct Student {
    char cno[3];
    char sno[3];
    double avg;

    bool operator < (const Student& i) const {
        if (strcmp(cno, i.cno) != 0) return strcmp(cno, i.cno) < 0;
        return avg > i.avg;
    }
};

int main()
{
    vector<Student> student;
    char s[4];
    while (cin >> s) {
        if (s[0] == '\\') break;
        Student tmp;
        strcpy(tmp.cno,s);
        cout << s << endl;
        cin >> s;
        strcpy(tmp.sno, s);
        cin >> tmp.avg;

        student.push_back(tmp);
    }
    sort(student.begin(), student.end());
    puts("cno\tsno\tavg");

    for (int i = 0; i < student.size(); i++) {
        cout << student[i].cno << '\t' << student[i].sno << '\t' << student[i].avg<< endl;
    }
    return 0;
}
/*
kc1 abc 66
kc1 pvz 99
kc2 kfc 88
kc3 hiv 50
\
*/

其中程序最下方是输入的元素, 这里注意一下Student结构体中char cno[3], char sno[3]声明位置上是相邻的。当我运行程序输入数据之后输出是:


cno     sno     avg
kc1abc  abc     66
kc1pvz  pvz     99
kc2kfc  kfc     88
kc3hiv  hiv     50

我疑问的点是cno数组长度为3,但是最终输出cno时连带sno数组也输出了,调试了很多次,发现如果在Student结构体中像下面这样声明变量,就不会出现这种问题:

struct Student {
    char cno[3];
    double avg;
    char sno[3];

    bool operator < (const Student& i) const {
        if (strcmp(cno, i.cno) != 0) return strcmp(cno, i.cno) < 0;
        return avg > i.avg;
    }
};

就是不将char cno[3] 和 sno[3] 声明分开。
最后我觉得多输出的原因是第一中声明方式上 cno 与 sno在地址上是连续的。 采用首地址输出字符型数据时遇到空字符才结束。
最终正确输出为:

cno     sno     avg
kc1     pvz     99
kc1     abc     66
kc2     kfc     88
kc3     hiv     50

  • 写回答

3条回答 默认 最新

  • VRJerry 2024-01-22 21:35
    关注

    我同意你最后说的原因。

    本身来讲还是你程序中的要求比较奇怪,输入上长度是4,而存储数组长度却是3,摆明了没有留结束\0的位置。同时目前平均值都是比较小的整数,你改成第二种,不知道如果遇到avg是个负数或者其他情况,且先赋值avg再赋值sno,是否会出现\0覆盖double部分数值的情况。

    为了正确输出,有没有一种可能,如果你声明的结构体成员变量数组长度变成4,能带着\0,就没问题了呢?
    因为字符串的话,输出就会一直到\0为止。而你的输入字符串长度4,拷贝字符串长度3,虽然不清楚拷贝的时候字符串结束那个\0是否会覆盖到比如avg或者sno的高位部分,但是至少说你再次赋值avg或者sno的时候,这个\0一定是被覆盖掉了的

    如果你结构体里的数组长度不动,那么声明输出的时候,是否逐字符输出,直到长度等于3为止(或者拼成新的字符串)应该也可以实现正确的输出,但肯定没有这样省事儿

    本回答被专家选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 2月2日
  • 专家已采纳回答 1月25日
  • 修改了问题 1月22日
  • 创建了问题 1月22日