Not Displaying all of my character array

i was having an issue earlier with my program displaying garbage but i think i figured out that problem. my program gets 3 pieces of info a "tracking number" a "description" and a "price". my issue is when trying to display the description from my linked list it only displays the first letter of the array. i dont know what im doing wrong.

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;


struct node
{
	float TrackNum;
	char Desc[35];
	double Charge;
	node *link; //pointer to the next record

};

node* HeadPointer = NULL;

void InsertItem ( float, char [35], double, node * );
void PrintList (node * );

int main()
{

	char ContFlag = 'Y';
	float InitTrackNum = '\0'; 
	char InitDesc[35] = "\0";
	double InitCharge = '\0';
	node* CurrentRecordPointer = NULL;

	char NextChar = '\0';

	while (toupper(ContFlag) == 'Y')
	{

		//Getting tracking number
		cout << "Enter tracking number: ";
		cin >> InitTrackNum;
		cout << endl;

		//Getting Description
		cout << "Enter Description: ";

		NextChar = cin.peek();
		
		if (NextChar == '\n' )
		{
			cin.ignore();
		}

		cin.get(InitDesc, 35);
		cout << endl;

		//Getting charge
		cout << "Enter charge: ";
		cin >> InitCharge;
		cout << endl;

		CurrentRecordPointer = new node;

		InsertItem( InitTrackNum, InitDesc, InitCharge, CurrentRecordPointer);
		HeadPointer = CurrentRecordPointer;


		cout << "Do you wish to enter more data? ( 'Y' or 'N' ) ";
		cin>> ContFlag;

	}

	cout << endl << endl;
	
	PrintList (HeadPointer); //sending what ever variable represents the head of the list

return 0;

}//end of main

//insert data into the linked list and set link to next node
void InsertItem (float InitTrackNum, char* InitDesc, double InitCharge, node *CurrentRecordPointer)
{
	
	CurrentRecordPointer->TrackNum = InitTrackNum;
	CurrentRecordPointer->Desc[35] = *InitDesc;
	CurrentRecordPointer->Charge = InitCharge;
	CurrentRecordPointer->link = HeadPointer;
	
	

	
	
}

void PrintList (node *Head)
{
	cout << setw(12)<<left<<"Tracking"<<setw(35)<<left<<"Type of Animal"<<setw(14)<<left<<"Daily Boarding"<<endl;
	cout <<	setw(12)<<left<<"Number"<<setfill(' ')<<setw(35)<<" "<<setw(14)<<left<<"Charge"<<endl;
	cout << setw(60)<< setfill('-')<<" "<<endl;
	cout << setfill(' ');

	while (Head != NULL )
	{
		cout <<setw(12)<<left<< Head->TrackNum << setw(35) << Head->Desc[35] << setw(14) << Head->Charge << endl;
		Head = Head->link;
	}

}
1
2
// Undefined behavior!  Even if it did work the syntax could only result in one character being copied
CurrentRecordPointer->Desc[35] = *InitDesc;


You cannot copy strings this way. There are a number of fixes.

1) use std::string and getline. std::string provides built in copy constructor and assignment operator and you don't have to worry about strings that are too large being entered by the user.

2) use strcpy to copy the string. Desc[35] is an out of bounds access. Use a constant to define the size of the array and then use a strcpy to copy the data.

If I were you, I would rewrite the string processing to use std::string. I don't see any reason to mess around with character arrays in that example since it is clearly a C++ program.
Last edited on
Thanks for your reply!

now im a total programming newb im not quite sure what you mean. Ive tried to use a string instead of a character array, but i need to be able to have spaces in the description. When i use a string and input a something with a space in it the program crashes and just goes into a loop. any way you can dumb it down a little. and maybe an example? i would rather learn how to do it instead of actually just getting the code tho
Last edited on
// Quote::kramman: "i would rather learn how to do it instead of actually just getting the code tho"
// So true...
Take a look at this example. You need to use getline with std::string. You might be using cin which will stop when it reaches a space where getline will read an entire line.
http://www.cplusplus.com/reference/string/getline/

Also take a look at this link. Instead of explicitly checking for '\n' just use the numeric_limits to ignore the extra characters after using cin for the integer inputs.
http://www.parashift.com/c++-faq-lite/input-output.html#faq-15.3

Try copying the examples at those links and I think that you should be able to use them within your code. Repost the latest thing that you are working on if you run into trouble and someone will offer help as long as it looks like you are making progress on your own.
Thanks for the info will do!
ok I seem to have gotten it working. As i understand it the getline just reads everything from the input stream and ignores any endline characters so my
1
2
3
4
5
6
NextChar = cin.peek();
        
        if (NextChar == '\n' )
        {
            cin.ignore();
        }

isnt really necessary. Since im not trying to convert from a string pointer to a char array and just copy a string to a string my InsertItem function works too. Are my thoughts correct?

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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;


struct node
{
	float TrackNum;
	string Desc;
	double Charge;
	node *link; //pointer to the next record

};

node* HeadPointer = NULL;

void InsertItem ( float, string, double, node * );
void PrintList (node * );

int main()
{

	char ContFlag = 'Y';
	float InitTrackNum = '\0'; 
	string InitDesc = "\0";
	double InitCharge = '\0';
	node* CurrentRecordPointer = NULL;

	char NextChar = '\0';

	while (toupper(ContFlag) == 'Y')
	{

		//Getting tracking number
		cout << "Enter tracking number: ";
		cin >> InitTrackNum;
		cout << endl;

		//Getting Description
		cout << "Enter Description: ";

		NextChar = cin.peek();
		
		if (NextChar == '\n' )
		{
			cin.ignore();
		}

		getline(cin, InitDesc);
		cout << endl;

		//Getting charge
		cout << "Enter charge: ";
		cin >> InitCharge;
		cout << endl;

		CurrentRecordPointer = new node;

		InsertItem( InitTrackNum, InitDesc, InitCharge, CurrentRecordPointer);
		HeadPointer = CurrentRecordPointer;


		cout << "Do you wish to enter more data? ( 'Y' or 'N' ) ";
		cin>> ContFlag;

	}

	cout << endl << endl;
	
	PrintList (HeadPointer); //sending what ever variable represents the head of the list

return 0;

}//end of main

//insert data into the linked list and set link to next node
void InsertItem (float InitTrackNum, string InitDesc, double InitCharge, node *CurrentRecordPointer)
{
	
	CurrentRecordPointer->TrackNum = InitTrackNum;
	CurrentRecordPointer->Desc = InitDesc;
	CurrentRecordPointer->Charge = InitCharge;
	CurrentRecordPointer->link = HeadPointer;
	
	

	
	
}

void PrintList (node *Head)
{
	cout << setw(12)<<left<<"Tracking"<<setw(35)<<left<<"Type of Animal"<<setw(14)<<left<<"Daily Boarding"<<endl;
	cout <<	setw(12)<<left<<"Number"<<setfill(' ')<<setw(35)<<" "<<setw(14)<<left<<"Charge"<<endl;
	cout << setw(60)<< setfill('-')<<" "<<endl;
	cout << setfill(' ');

	while (Head != NULL )
	{
		cout <<setw(12)<<left<< Head->TrackNum << setw(35) << Head->Desc << setw(14) << Head->Charge << endl;
		Head = Head->link;
	}

}
Read the second link that I showed you completely. You need to skip past the '\n' after using cin to read the integers otherwise getline will not work. It also provides an alternative which is much simpler than what you are doing. Moreover, it shows you how to deal with invalid inputs which is something that you should add to the program regardless. It looks like you are on the right track. You can also pass the string objects to functions by const reference, which will help you to avoid unnecessary copies.

void InsertItem (float InitTrackNum, const string& InitDesc, ...)
Topic archived. No new replies allowed.