Problems with outputing data from a text file

Hi all, I really need some help and real fast. I am trying to simply display data from a textfile. Here is just some of the textfile Inventory.txt

Nokia Lumia 610#Nokia#Touch#8GB#8#Tango OS#3899.00#
Blackberry Curve 9380#Blackberry#Both#1GB#8#Blackberry OS 7#3499.00#
Samsung Galaxy S3#Samsung#Touch#32GB#8#Andriod#6999.00#
iPhone 4S#Apple#Touch#16GB#8#IOS#7899.00#

Each bit of information is separated by the hash and I am trying to store each in its own variable. The variable are name, manufacturer, design,internal memory,camera, operating system and price(They are all in one structure). Ive completed the program but when I want to run it, it looks like it outputs the the first line correctly but everything else is zeros.Also I cant seem to get everything in seperate columns. Can someone take a look at my code and maybe fix the slight error and explain to me what I did wrong. CAN SOMEONE HELP ME RIGHT NOW PLEASE

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
#include<fstream>
#include<iostream>
#include<string>
using namespace std;

struct CellphoneInfo
{
	string name[100];
	string manu[100];
	string cellDesign[100];
	string internalMem[100];
	string camera[100];
	string os[100];
	double costPrice[100];
};

void outputData(CellphoneInfo [],int);
int main()
{
	string input;
	const int size = 100;
	
	CellphoneInfo cellphone[size];

	
	fstream dataFile("Inventory.txt",ios::in);
	
	if(dataFile)
	{
		for(int i = 0;i<size;i++)
		{
			getline(dataFile,cellphone[i].name[i],'#');
			getline(dataFile,cellphone[i].manu[i],'#');
			getline(dataFile,cellphone[i].cellDesign[i],'#');
			getline(dataFile,cellphone[i].internalMem[i],'#');
			getline(dataFile,cellphone[i].camera[i],'#');
			getline(dataFile,cellphone[i].os[i],'#');
			dataFile >> cellphone[i].costPrice[i];
		}		
		
		dataFile.close();
		cout << "File read in" << endl;
		outputData(cellphone,size);
		
	}
	else
	{
		cout << "Error: Cannot open file.\n";
	}
	return 0;
	
}

void outputData(CellphoneInfo arr [],int size)
{
	cout << "Cellphone Name\tManufacturer Name\tDesign\tInternal Memory\tCamera Megapixel\tOperating System\tCost Price\n\n"; 
	for(int i = 0;i < size;i++)
	{
		cout << arr[i].name[i] << "\t" << arr[i].manu[i] << "\t" << arr[i].cellDesign[i] << "\t" << arr[i].internalMem[i] << "\t" << arr[i].camera[i] << "\t" << arr[i].os[i] << "\t" << arr[i].costPrice[i];
	}
	cout << endl;
}
 
Last edited on
Use code tags,

and with fstream, shouldn't it be.

1
2
fstream dataFile;
dataFile.open("Inventory.txt", ios::in);
Either way it still reads from the textfile. Im having a problem with storing each segment in separate variables and displaying it separate columns that is readable. But thanks for helping anyways
And sorry for not using the code tags. Im new and still learning how every thing works
CAN SOMEONE HELP ME RIGHT NOW PLEASE

Really?

And sorry for not using the code tags. Im new and still learning how every thing works

Nothing is stopping you from hitting the edit button and putting them in. Look for the <> button.


1
2
3
4
5
6
7
8
9
10
struct CellphoneInfo
{
    string name[100];
    string manu[100];
    string cellDesign[100];
    string internalMem[100];
    string camera[100];
    string os[100];
    double costPrice[100];
};


Do you think one instance of CellphoneInfo should have 100 name, 100 manufacturers, 100 cell designs..?

When you get that straightened out, you also have a problem mixing formatted and unformatted (getline vs. >>) input extraction.
Last edited on
and with fstream, shouldn't it be.

1
2
fstream dataFile;
dataFile.open("Inventory.txt", ios::in);

That is one way of opening the file, but there is nothing wrong with opening the file using the constructor either. The following is also acceptable.
fstream dataFile("Inventory.txt",ios::in);

But since the OP doesn't seem to need both input and output I would recommend using the ifstream class over the fstream class.

1
2
3
4
ifstream dataFile("Inventory.txt");
// or
ifstream datafile;
datafile.open("Inventory.txt")


I also recommend always insuring that your file correctly by testing the stream state.
1
2
if(!datafile)
/// Error opening file, do something 


Last edited on
Hey cire

I set each instance to 100 elements because it is a large textfile, Im only showing you a part of it. But I dont quite understand what I am doing wrong with the getline vs >> input extraction. I used getline because it allows me to cut of at the delimeter(In this case the hash).

And if you could, can you run the source code and see the problem that I am having
Last edited on
I set each instance to 100 elements because it is a large textfile,


The size of the text file has nothing to do with a single instance of CellphoneInfo.

You have 100 CellphoneInfo objects in the cellphone array. Each of those have 100 names, 100 manufacturers, 100 designs...
Okay I understand now. Well I have taken the arrays out the structure. But that never the problem of displaying - When I run the program it displays the first line of the textfile and then weird numbers afterwards that are all spread out. Can someone help out!!!!!!!!!!

I changed some of the code but still not helping...Please can someone run the code to see the problem im getting...

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
#include<fstream>
#include<iostream>
#include<string>
using namespace std;

struct CellphoneInfo
{
	string name;
	string manu;
	string cellDesign;
	string internalMem;
	string camera;
	string os;
	double costPrice;
};

void outputData(CellphoneInfo [],int);
int main()
{
	string input;
	const int size = 100;
	
	CellphoneInfo cellphone[size];

	
	fstream dataFile;
	dataFile.open("Inventory.txt",ios::in);
	int count;
	
	if(dataFile)
	{
		while(dataFile)
		{
			count++;
			getline(dataFile,cellphone[count].name,'#');
			getline(dataFile,cellphone[count].manu,'#');
			getline(dataFile,cellphone[count].cellDesign,'#');
			getline(dataFile,cellphone[count].internalMem,'#');
			getline(dataFile,cellphone[count].camera,'#');
			getline(dataFile,cellphone[count].os,'#');
			dataFile >> cellphone[count].costPrice;
		}		
		
		dataFile.close();
		cout << "File read in" << endl;
		outputData(cellphone,count);
		
	}
	else
	{
		cout << "Error: Cannot open file.\n";
	}
	return 0;
	
}

void outputData(CellphoneInfo arr [],int count)
{
	cout << "CellName\tMan Name\tDesign\tMemory\tCamera\tOS\tPrice\n\n"; 
	for(int i = 0;i < count;i++)
	{
		cout << arr[i].name << "\t" << arr[i].manu << "\t" << arr[i].cellDesign << "\t" << arr[i].internalMem << "\t" << arr[i].camera << "\t" << arr[i].os << "\t" << arr[i].costPrice;
	}
	cout << endl;
}
Last edited on
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
    int count=0;

    if(dataFile)
    {
        while(dataFile)
        while ( getline(dataFile, cellphone[count].name, '#') )
        {
            count++ ;
            getline(dataFile,cellphone[count].name,'#');
            getline(dataFile,cellphone[count].manu,'#');
            getline(dataFile,cellphone[count].cellDesign,'#');
            getline(dataFile,cellphone[count].internalMem,'#');
            getline(dataFile,cellphone[count].camera,'#');
            getline(dataFile,cellphone[count].os,'#');
            dataFile >> cellphone[count].costPrice;

            // remove the trailing # and newline from the stream
            // to setup the next line for extraction.
            dataFile.ignore(2, '\n' ) ; 

            ++count;
        }		

        dataFile.close();
        cout << "File read in" << endl;
        outputData(cellphone,count);

    }


So, initialize count to 0. Only check the state of the stream after an input operation. (Ideally reading an entire record would be in it's own function, and you could loop on the success of that function, but we're going to assume that if we can get the first token from a line, the rest of the tokens will be there.) Update count after we read stuff into the array so that we aren't skipping the first element of the array, and remove the stuff from the input stream you weren't removing before that was throwing things off.
Thanks it works.Also should be making use of a pointer variable if im sending the cellphone array to other functions
Last edited on
HI ALL. Ive been working on my program alittle bit and I have run into another problem. I am trying to search for a record and display a single record from the array. But when I enter the id of the field that I am searching for, the function returns -1

Please help

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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
#include<fstream>
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;

struct CellphoneInfo
{
	string name;
	string manu;
	string cellDesign;
	string internalMem;
	string camera;
	string os;
	double costPrice;
};

void outputData(CellphoneInfo [],int);
double total(CellphoneInfo [],int);
int searchByName(CellphoneInfo [],int );

int main()
{
	const int size = 100;
	
	CellphoneInfo cellphone[size];
	
	fstream dataFile;
	dataFile.open("Inventory.txt",ios::in);
	int count =0;
	
	if(dataFile)
	{
		while(getline(dataFile,cellphone[count].name,'#'))
		{
			getline(dataFile,cellphone[count].manu,'#');
			getline(dataFile,cellphone[count].cellDesign,'#');
			getline(dataFile,cellphone[count].internalMem,'#');
			getline(dataFile,cellphone[count].camera,'#');
			getline(dataFile,cellphone[count].os,'#');
			dataFile >> cellphone[count].costPrice;
			
			dataFile.ignore(2,'\n');
			++count;
		}		
		
		dataFile.close();
		cout << "File read in" << endl;
		outputData(cellphone,count);
		
	}
	else
	{
		cout << "Error: Cannot open file.\n";
	}
			int element = searchByName(cellphone,count);
			cout << "\n\nElement: " << element;
			if (element != -1)
			{
			cout << "ID\tCell Model\tManu Name\tDesign\tMemory\tCamera\tOS\t\t\tPrice\n"; 
			cout << fixed << showpoint << setprecision(2);
			cout << element << "\t" << cellphone[element].name << "\t" << cellphone[element].manu << "\t" << cellphone[element].cellDesign << "\t" << cellphone[element].internalMem << "\t" << cellphone[element].camera << "\t" << cellphone[element].os << "\t\t" << cellphone[element].costPrice << endl;
			}
	return 0;
	
}

int searchByName(CellphoneInfo item [],int size)
{
	int choice;	
	outputData(item,size);
	string modelName;
	int id;
	
	
	cout << "\n***Search***\n";
	cout << "1. Apple\n";
	cout << "2. Blackberry\n";
	cout << "3. Nokia\n";
	cout << "4. Samsung\n";
	cout << "5. Sony\n";
	cout << "Enter the corresponding number of the Model that you would like to search for: ";
	cin >> choice;
	switch(choice)
	{
			case 1: modelName = "Apple     ";
				break;
			case 2: modelName = "Blackberry";
				break;
			case 3: modelName = "Nokia     ";
				break;
			case 4: modelName = "Samsung   ";
				break;
			case 5: modelName = "Sony      ";
				break;
		default: 
			cout << "Invalid choice. To try again, run the program again.\n";
	}
	
	cout << "\nEnter ID of the " << modelName << ": ";
	cin >> id;
	
	int index = 1;
	int position = -1;
	bool found = false;
	
	while(index < size && !found)
	{
		if(item[index].manu == modelName && index == id)
		{
			found = true;
			position = index;
		}
		index++;
	}
	return position;
}

void outputData(CellphoneInfo arr [],int count)
{
	cout << "ID\tCell Model\tManu Name\tDesign\tMemory\tCamera\tOS\t\t\tPrice\n\n"; 
	cout << fixed << showpoint << setprecision(2);
	for(int i = 0;i < count;i++)
	{
		cout << (i+1) << "\t" << arr[i].name << "\t" << arr[i].manu << "\t" << arr[i].cellDesign << "\t" << arr[i].internalMem << "\t" << arr[i].camera << "\t" << arr[i].os << "\t\t" << arr[i].costPrice << endl;
	}
	cout << endl;
}
case 1: modelName = "Apple ";

"Apple " will not compare equal to a string that contains "Apple"

1
2
	cout << "\nEnter ID of the " << modelName << ": ";
	cin >> id;


What's this index/id business? id is apparently supposed to correlate with index, and somehow the user is supposed to magically know where the computer is going to find the name when it searches? Why not just take the user's "id" and use that, then?

Array indexing begins at 0.
Ok fixed it. Im now trying to sort the array in alphabetical order by manufacterer name but im not sure how. Ive already completed another fuction that sorts according to cost price. But because the manu is of type string, I cant get anything to work

This is the function that sorts by costPrice

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
void displayByPrice(CellphoneInfo cellphone[],int size)
{
	double temp;
	string temp1;
	int i,j;
	for(i = size;i>=0;i--)
	{
		for(j = 1;j <=i;j++)
		{
			if(cellphone[i].costPrice > cellphone[j].costPrice)
			{
				temp = cellphone[j].costPrice;
				cellphone[j].costPrice = cellphone[i].costPrice;
				cellphone[i].costPrice = temp;
				
				temp1 = cellphone[j].name;
				cellphone[j].name = cellphone[i].name;
				cellphone[i].name = temp1;
				
				temp1 = cellphone[j].manu;
				cellphone[j].manu = cellphone[i].manu;
				cellphone[i].manu = temp1;
				
				temp1 = cellphone[j].cellDesign;
				cellphone[j].cellDesign = cellphone[i].cellDesign;
				cellphone[i].cellDesign = temp1;
				
				temp1 = cellphone[j].internalMem;
				cellphone[j].internalMem = cellphone[i].internalMem;
				cellphone[i].internalMem = temp1;
				
				temp1 = cellphone[j].camera;
				cellphone[j].camera = cellphone[i].camera;
				cellphone[i].camera = temp1;
				
				temp1 = cellphone[j].os;
				cellphone[j].os = cellphone[i].os;
				cellphone[i].os = temp1;
			}
		}
	}
	outputData(cellphone,size);
}


You can condense that quite a bit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
void displayByPrice(CellphoneInfo cellphone[], int size)
{
    for ( unsigned i=0; i<size-1;  ++i )
    {
        for ( unsigned j=i+1; j<size; ++j )
        {
             if ( cellphone[i].costPrice > cellphone[j].costPrice )
             {
                 Cellphone info temp = cellphone[j] ;
                 cellphone[j] = cellphone[i] ;
                 cellphone[i] = temp ;
             }
        }
    }
    outputData(cellphone,size) ;
}


And you should be able to use the same method to sort on std::string.

[ edit: I didn't notice your loop conditions. Seems a little convoluted, and unless I'm reading things wrong, the zeroth element will never be sorted. ]
Last edited on
I am trying to create a delete function that deletes an item from the array and all elements after, move up one element . Can you help with that too.

And this will be the last question of the program

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
void deleteItem(CellphoneInfo cell[],int size)
{
	int element;
	char answer;
	element = searchByID(cell,size);
	if (element != -1)
	{
		cout << "ID\tCell Model\tManu Name\tDesign\tMemory\tCamera\tOS\t\tPrice\n\n"; 
		cout << fixed << showpoint << setprecision(2);
		cout << element+1 << "\t" << cell[element].name << "\t" << cell[element].manu << "\t" << cell[element].cellDesign << "\t" << cell[element].internalMem << "\t" << cell[element].camera << "\t" << cell[element].os << "\tR " << cell[element].costPrice << endl;
		cout << "\nAre you sure you want to delete this item[Y/N]: ";
		cin >> answer;
		
		if (toupper(answer) == 'Y')
		{
			for(int i = element -1;i<size;++i)
			{
				cell[i] = cell[i+1];
				
				std::copy(cell+(element+1),cell+size,cell+(element-1));
				cout << "\n\nItem Deleted\n\n";
				showMenu(cell,size);
			}
		}
		else
			showMenu(cell,size);
	}
	else
		cout << "Invalid search.\n\n";	
}


Can Someone Help Please
Last edited on
Topic archived. No new replies allowed.