char* mystery output

for first b->readData() i get
Enter Student name:
Enter Student surname:
Enter Student ID:

but for second on i get
Enter Student name: Enter Student surname:
Enter Student ID:

why I'm getting it together for second one and not separate as in first? and how to get it to be separate.
Pls keep in mind that its explicit asked from me to use char* and also object Student in main must be dynamic

1
2
3
4
5
6
7
8
// untitled.h
class Student {
	char* name = new char[30];
	char* surname = new char[30];
	int ID;
public:
	void readData();
};


1
2
3
4
5
6
7
8
9
10
11
12
13
// untitled.cpp
#include "untitled.h"
#include <iostream>
#include <cstring>

void Student::readData() {
	std::cout << "Enter Student name: ";
	fgets(name, 30, stdin);
	std::cout << "Enter Student surname: ";
	fgets(surname, 30, stdin);
	std::cout << "Enter Student ID: ";
	std::cin >> ID;
}


1
2
3
4
5
6
7
8
9
10
11
12
13
14
// main.cpp
#include "untitled.h"
#include <iostream>

int main() {
	while (true) {
		Student *b = new Student;
		b->readData();
		b->readData();

		delete b;
	}
	return 0;
}
why are you mixing C's input and C++'s output?

try cin, or getline, or whatever instead of fgets.

if allowed to, you may also want to use c++ strings <string>
string str;
cin >> str; //like that. I see you can't here, but you really should learn these when you can, even if the teacher does not want them, as it is the way to go in c++.

mixing C and C++ I/O sometimes leaves the input and output streams in weird states that cause these kinds of issues.

your class should eventually add a destructor to free that memory for the C strings.
Last edited on
cin >> and fgets() don't get on with each other.

First, why fgets() and not cin.getline()? .getline() is the C++ way of obtaining a line of input.

>> ignores leading white space, extracts as required until a white space char and LEAVES the white space char in the buffer.

.getline() extracts all chars up to and including the trailing delimiter (\n if not specified). It does not ignore any leading white space chars.

so if you have a >> followed by a .getline(), the .getline() finds the \n left by the >> and treats it as a null input. Hence the result you see.

The 'easy' fix is to add a std::cin.ignore() after the >>

https://cplusplus.com/reference/istream/basic_istream/getline/
I must do it with char*, i tried using cin but then my program crash

Edit: I just used cin for this example and it work here, this is part of the bigger program and there it didn't worked with cin, I'll try again
Last edited on
OK. So L8 becomes:

1
2
//fgets(name, 30, stdin);
std::cin.getline(name, 30);



and similar for line 10.

Then after L12

 
std::cin.ignore();

Ok I got it worked finally as inteded with cin, (getline give me same problem as fgets) but after all methods are called I get this error:

HEAP CORRUPTION DETECTED: after Normal block (#218) at 0x0000017488EB5A60.
CRT detected that application wrote to memory after end of heap buffer.
Last edited on
did you free all your memory properly, including the strings in the class?
this error is a memory problem, and given what you are doing, likely one of these:
- failed to free some memory
- tried to release same memory twice
- wrote past end of buffer in one of your strings (string > 30 chars + ending zero)
- etc.
As 1 file, then consider:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <iostream>

class Student {
	char* name { new char[30] };
	char* surname { new char[30] };
	int ID {};

public:
	Student() {};
	void readData();
	void displayData() const;

	Student(const Student&) = delete;
	Student& operator=(const Student&) = delete;

	~Student() {
		delete[] name;
		delete[] surname;
	}
};

void Student::readData() {
	std::cout << "Enter Student name: ";
	std::cin.getline(name, 30);

	std::cout << "Enter Student surname: ";
	std::cin.getline(surname, 30);

	std::cout << "Enter Student ID: ";
	std::cin >> ID;
	std::cin.ignore();
}

void Student::displayData() const {
	std::cout << "ID: " << ID << "\nName: " << name << "\nSurname : " << surname << '\n';
}

int main() {
	while (std::cin) {
		const auto b { new Student };

		b->readData();
		b->displayData();
		delete b;
	}
}


where eof (ctrl Z for windows) terminates the loop.
I finally got rid of HEAP CORRUPTION error (I didnt type destructor here but I have it in my code), but I made stupid mistake when allocating memory for on of other dynamic variables I have.
I used () instead of [] and was so focused on why I'm gettingEnter Student name: Enter Student surname: together that I thinked this must be correlated to that, but it was just stupid typing mistake.
Now all work correctly
Last edited on
@seeplus
I tried your code and it work just fine, but for class purposes I need it in 3 files and as I mention above this is just part of the program, and there I again have this problem where Enter Student name: Enter Student surname: are together when using getline, but when using just std::cin>>name; std::cin>>surname; I dont have that. Anyway thanks for help and I hope to never again use char* after this semester.
where Enter Student name: Enter Student surname: are together when using getline


Then you haven't added the cin::ignore() as suggested. Also >> with a string will only extract from the input only to the first white space.

My code as above doesn't have this issue.


Enter Student name: foo
Enter Student surname: bar
Enter Student ID: 123
ID: 123
Name: foo
Surname : bar
Enter Student name: bar
Enter Student surname: foo
Enter Student ID: 234
ID: 234
Name: bar
Surname : foo


If you are still having the issue, I suggest you post you complete current code.
Registered users can post here. Sign in or register to post.