繁体   English   中英

我的程序控制台输出中出现未知的ASCII代码字符

[英]I am getting unknown ascii code characters in my program console output

我的程序基本上要求用户输入,并将诸如登录数据,用户名之类的数据保存在文本文件中,并使用相同的文件来检索数据并在输出控制台中显示。 程序执行时,用户可以在选项1到6之间进行选择,选项6用于应用程序中现有的选项,其余选项1到5用于用户输入数据并查看文件中的存储数据。

当程序在控制台中显示数据时,我看到许多不必要的ASCii代码。 为什么会显示出来,如何使它们消失? 谢谢!!

int main() {
    //Considering the max length of data entered (name) to be 15.
    char data[15];
    int n = 0, option = 0, count_n = 0;
    //This is the initial mark alloted to a subject.
    string empty = "00";
    string proctor = "";
    //Name of the file in which DB is stored.
    ifstream f("Example.txt");
    string line;

    //The following for loop counts the total number of lines in the file.
    for (int i = 0; std::getline(f, line); ++i) {
        count_n++;
    }

    while (option != 6) {
        //This prints out all the available options in the DB
        cout << "\nAvailable operations: \n1. Add New Students\n2."
            << "Student Login\n3. Faculty Login\n4. Proctor Login\n5. Admin View\n"
            << "6. Exit\nEnter option: ";
        cin >> option;

        if (option == 1) {
            cout << "Enter the number of students: ";
            cin >> n;

            count_n = count_n + n;

            for (int i = 0; i < n; i++) {
                ofstream outfile;
                outfile.open("Example.txt", ios::app);
                //The entire data of a single student is stored line-by-line.
                cout << "Enter your registration number: ";
                cin >> data;
                outfile << data << "\t";

                cout << "Enter your name: ";
                cin >> data;
                int len = strlen(data);

                while (len < 15) {
                    data[len] = ' ';
                    len = len + 1;
                }
                outfile << data << "\t";
                //Inserting empty data initially into the file
                outfile << empty << "\t";
                outfile << empty << "\t";
                cout << "\b \b";

                cout << "Enter your proctor ID: ";
                cin >> proctor;

                outfile << proctor << endl;

            }
        }

        else if (option == 2) {
            char regno[9];
            cout << "Enter your registration number: ";
            cin >> regno;
            ifstream infile;
            int check = 0;
            infile.open("Example.txt", ios::in);

            //This loop prints out the data according to the registration number specified.
            while (infile >> data) {
                if (strcmp(data, regno) == 0) {
                    cout << "\nRegistration Number: " << data << endl;
                    infile >> data;
                    cout << "Name: " << data << endl;

                    infile >> data;
                    cout << "CSE1001 mark: " << data << endl;

                    infile >> data;
                    cout << "CSE1002 mark: " << data << endl;

                    infile >> data;
                    cout << "Proctor ID: " << data << endl;

                    infile.close();
                    check = 1;
                }
            }

            if (check == 0) {
                cout << "No such registration number found!" << endl;
            }

        }

        //This loop is used to view and add marks to the database of a student.
        else if (option == 3) {
            char subcode[7];
            cout << "Enter your subject code: ";
            cin >> subcode;
            string code1 = "CSE1001", code2 = "CSE1002", mark = "";
            ifstream infile;
            int check = 0;

            cout << "\nAvailable operations: \n1. Add data about marks\n"
                << "2. View data\nEnter option: ";
            cin >> option;

            if (option == 1) {
                cout << "Warning! You would need to add mark"
                    << "details for all the students!" << endl;
                for (int i = 0; i < count_n; i++) {
                    fstream file("Example.txt");

                    //The seek in file has been done according to the length
                    //of the data being inserted. It needs to adjusted accordingly
                    //for diffferent lengths of data.

                    if (strcmp(subcode, code1.c_str()) == 0) {
                        file.seekp(26 + 37 * i, std::ios_base::beg);
                        cout << "Enter the mark of student#" << (i + 1) << " : ";
                        cin >> mark;
                        file.write(mark.c_str(), 2);
                    }

                    if (strcmp(subcode, code2.c_str()) == 0) {
                        file.seekp(29 + 37 * i, std::ios_base::beg);
                        cout << "Enter the mark of student#" << (i + 1) << " : ";
                        cin >> mark;
                        file.write(mark.c_str(), 2);

                    }
                }

            }

            //This loop is used to view marks of a student.
            //The extra infile commands have been used to get a specific mark 
            //only since the data has been seperated by a tabspace.

            else if (option == 2) {
                infile.open("Example.txt", ios::in);
                if (strcmp(subcode, code1.c_str()) == 0) {
                    cout << "Registration number - Marks\n" << endl;
                    while (infile >> data) {
                        cout << data;
                        infile >> data;
                        infile >> data;
                        cout << " - " << data << endl;
                        infile >> data;
                        infile >> data;
                        check = 1;
                    }
                }

                infile.close();
                infile.open("Example.txt", ios::in);

                if (strcmp(subcode, code2.c_str()) == 0) {
                    cout << "Registration number - Marks\n" << endl;
                    while (infile >> data) {
                        cout << data;
                        infile >> data;
                        infile >> data;
                        infile >> data;
                        cout << " - " << data << endl;
                        infile >> data;
                        check = 1;

                    }
                }
            }

            infile.close();

            if (check == 0) {
                cout << "No such subject code found!" << endl;
            }

        }

        //This loop displays all the details of students under the same proctor ID. 

        else if (option == 4) {
            char procid[7];
            cout << "Enter your proctor ID: ";
            cin >> procid;
            int check = 1;
            char temp1[100], temp2[100], temp3[100];
            char temp4[100], id[100];
            ifstream infile;
            infile.open("Example.txt", ios::in);

            while (infile >> temp1) {
                infile >> temp2;
                infile >> temp3;
                infile >> temp4;
                infile >> id;

                if (strcmp(id, procid) == 0) {
                    cout << "\nRegistration Number: " << temp1 << endl;
                    cout << "Name: " << temp2 << endl;
                    cout << "CSE1001 Mark: " << temp3 << endl;
                    cout << "CSE1002 Mark: " << temp4 << endl;
                    check = 1;
                }
            }

            if (check == 0) {
                cout << "No such proctor ID found!" << endl;
            }
        }

        //This loop acts as an admin view to see all the data in the file.

        else if (option == 5) {
            char password[25];
            cout << "Enter the admin password: ";
            cin >> password;

            //This variable value can be changed according to your requirement 
            //of the administrator password.

            string admin_pass = "admin";

            if (strcmp(password, admin_pass.c_str()) == 0) {
                cout << "Reg No.     \tName\tCSE1001\tCSE1002\tProctor ID" << endl;
                ifstream infile;
                infile.open("Example.txt", ios::in);
                char data[20];

                while (infile >> data) {
                    cout << data << "\t";
                    infile >> data;
                    cout << data << "\t";
                    infile >> data;
                    cout << data << "\t";
                    infile >> data;
                    cout << data << "\t";
                    infile >> data;
                    cout << data << endl;

                }
            }
        }
    }
}

这是输出:

在此处输入图片说明

╠字符是方框图字符 在代码页437中,它由十六进制值0xCC表示。

在这种情况下,它是一个不可思议的十六进制值 ,表示它是未初始化的堆栈存储器。

data数组的长度为20个字符,但会退化为指针,并且operator<<输出字符,直到获得空字符为止。 因此,在这种情况下,许多未初始化的内存╠字符,直到在内存中找到\\0字符为止。


似乎未初始化的data变量是在上一次运行时写入文件的,现在可以原样读取。 如果读取失败,则可能在data char数组的第一个位置放置了\\0 ,并且在这种情况下将没有输出。

我使用一个空的输入文件运行该程序,并添加了一个学生。 这存储在文本文件中(使用Visual Studio的文本编辑器查看):

REGNUM123   Pete           ÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌÌ    00  00  PROC432

在这种情况下,带有严重字符的capital或大写Ì i是Unicode和其他多种编码0xCC十六进制值。 添加学生时,写入的字符数不一定等于data数组中的字符数(在这种情况下为15)。 写入它们直到找到\\0

最有可能您有多个缓冲区溢出:

        char password[25];
        cout << "Enter the admin password: ";
        cin >> password;

如果有人输入超过24个字节(字符)的密码,则密码缓冲区溢出。 您应该这样进行:

        std::string password;
        cout << "Enter the admin password: ";
        cin >> password;

对于输出而言,同样的事情是有效的,您可能会缓冲区溢出char data[20]; 此外,您不能使用infile >> data来读取文件。 您必须使用infile.getline()

int col_count = 4;

while (true) {
    infile.getline(data, 20);  // 20 is the size of the buffer.
    if(infile.good()) {
        cout << data;
        if(--col_count == 0) {
            col_count = 4;
            cout << '\n';
        }
        else cout << '\t';
    }
    else break;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM