Write/Read struct array data table C++ - c++

Im fairly new to c++ and I've spent about six hours on this, sadly with no result.
im trying to do the following. (for my own practice)
Make a navigation menu like in cmd. #done
Create two structs with the concept of "uml aggregation" #done
Make function for input, output, sort by a value, etc. #done
Write everything to a file #Struggling from this point.
Read back from the file.
Use the data later(sort by name, delete last object, add new...etc)
I have a massive code that I think will be silly to post (and a waste of time) so I'll just post a simpler version.
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string.h>
using namespace std;
struct man{
char name[20];
int age;
};
struct group{
man* men[3];
};
void fill( man &y);
void show( man &y);
void input(group &x, man &y);
void output(group &x, man &y);
int main(){
man q;
group w;
input(w, q);
cout<<endl;
output(w, q);
ofstream w1file("B.dat");
for (int i=0; i<2; i++){
w1file.write((char*) &w.men[i]->name, 20);
w1file.write((char*) &w.men[i]->age, sizeof(int));
}
w1file.close();
ifstream r1file("B.dat");
while(r1file.good()){
r1file.read((char*) &w.men[0]->name, 20);
r1file.read((char*) &w.men[0]->age, sizeof(int));
r1file.read((char*) &w.men[1]->name, 20);
r1file.read((char*) &w.men[1]->age, sizeof(int));
}
output(w, q);
r1file.close();
system("pause");
return 0;
}
void fill( man &y){
gets(y.name);
cin>>y.age;
cin.ignore();
}
void show( man &y){
cout<<y.name<<endl;
cout<<y.age<<endl;
}
void input(group &x, man &y){
x.men[2]= new man[2];
for (int i=0; i<2;i++){
fill(y);;
x.men[i]= new man(y);
}
}
void output(group &x, man &y){
for (int i=0; i<2;i++){
show(*x.men[i]);
}
}
if i remove the writing part, then the program just crashes as soon as i press run.
ive tried it like this, and with file>>"variable"... ive tried it with only first element...tried to copy the whole thing to an array, write the array and then read it, but nothing works :(
I also want it to output the data in the file like this: (example)
#in the txt, dat, whatever
John 21
Pier 18...etc
So i can edit the data directly from the written file.
but what im getting is this:
John н# А…J { Adam ed н# А…J Х
My initial idea was to make a program that outputs data to files in the form of tables(hope you understand me)
exmpl.
name1 age1 wage1 married/not married1
name2 age2 wage2 married/not married2
name3...age3...etc
Can someone from heaven please help me with this and if possible explain what im doing wrong?

for (int i; i<2; i++){
Looks at this line, until you see the problem. Keep looking at it, until you do.
Hint: what do you expect the first value of i to be, in this loop?
P.S.: Why are you allocating a single instance of man, for men[0] and men[1], and two instances of man, for men[2]?

There are several problems:
The writing for uses an uninitialized variable i, so that it starts with an undetermined value. Try :
for (int i=0; i<2; i++){ //i=0 !!
Then you write binary data in a file open in the default text mode. This can, depending on the binary value and the operating system alter what is effectively written in the file. So:
ofstream w1file("B.dat", ios::binary); // binary mode instead of text mode
The same applies of course to the reading stream.
Note that you could have from 0 to 3 men in the group. It would be wise to write at the beginning of the group the number of items. So when reading the group you could first read the number of items to be expected and loop until you have read them all. Your current reading loop is weird, as it will read the file and constantly overwrite the 2 first mens (if there are more data in the file).
The way you could properly read would be:
const int maxmen=3;
for (int i=0; i<maxmen && r1file.read((char*) &w.men[i]->name, 20)
&& r1file.read((char*) &w.men[0]->age, sizeof(int)); i++)
cout << "Successfuly read item "<<i<<endl;
}
Note also that this code is heavily leaking memory.

Related

How to use ifstream

I have a problem with my program which basically is a simple math program. It does some vector multiplication and vector matrix multiplication and it does work fine until i try to read data from a text. I can compile the program but when i try to execute it, I get the fault:" Dataname.exe does not work".
Here's my code. Do not consider the cins and couts
#include<iostream>
#include<cmath>
#include<vector>
#include"header.hpp"
#include<fstream>
using namespace std;
int main()
{
ifstream einlesen ("Zahlen.dat"); //function "einlesen" opens the file "Zahlen.dat".
if (einlesen) // Message if the file has been opend
cout<<"Daten wurden eingelesen"<<endl;
else {
cout<<"Konnte Daten nicht einlesen"<<endl;
return 99;
}
double a;
int n{0};
while ( einlesen >>a>>a>>a>>a>>a>>a>>a) n++;//Loop copys datas on a
einlesen.clear();//stops the loop after the last data is copied.
einlesen.seekg(0, ios_base::beg);//??
vector<double> vecein(n), vecein1(n),Matrixein(n);
for (a = 0;a<n;a++);//copys datas to a vector further calculations
{
einlesen>>vecein.at(a);
einlesen>>vecein1.at(a);
einlesen>>Matrixein.at(a);
}
double Matrix1[9]; //defining my Matrix and the coordinates of my vectors.
double x,y,z,x_1,x_2,x_3;
vector<double> vec(3);
vector<double> vec1(3);
// Old code where I read the data with `cin`:
/*cout<<"Geben Sie die x Koordinaten ein:"<<endl;
cin>>vec[0];
cin>>vec1[0];
cout<<"Geben Sie die y Koordinaten ein:"<<endl;
cin>>vec[1];
cin>>vec1[1];
cout<<"Geben Sie die z Koordinaten ein:"<<endl;
cin>>vec[2];
cin>>vec1[2];
cout<<"Geben Sie eine Matrix ein"<<endl;
cin>>Matrix1[0]>>Matrix1[1]>>Matrix1[2]>>Matrix1[3]>>Matrix1[4]>>Matrix1[5]>>Matrix1[6]>>Matrix1[7]>>Matrix1[8];
cout<<"Vektor1:<"<<vec[0]<<","<<vec[1]<<","<<vec[2]<<">"<<endl;
cout<<"Vektor2:<"<<vec1[0]<<","<<vec1[1]<<","<<vec1[2]<<">"<<endl;
vector<double> Addition(3);
Addition = Vektoraddition(vec,vec1);
cout<<"Addition:"<<"<"<<Addition[0]<<","<<Addition[1]<<","<<Addition[2]<<">"<<endl;
double Skalarprodukt;
Skalarprodukt = Skalarpr(vec,vec1);
cout<<"Skalarprodukt:"<<Skalarprodukt<<endl;
vector<double> kreuzprodukt(3);
kreuzprodukt = Kreuzprodukt (vec,vec1);
cout<<"Kreuzprodukt:"<<"<"<<kreuzprodukt[0]<<","<<kreuzprodukt[1]<<","<<kreuzprodukt[2]<<">"<<endl;
vector<double> MatrixVektor(3);
MatrixVektor = Matrix_vektor (Matrix1, vec);
cout<<"Matrix*Vektor:"<<"<"<<MatrixVektor[0]<<","<<MatrixVektor[1]<<","<<MatrixVektor[2]<<">"<<endl;*/
ofstream ausgabe ("Ausgabe.dat");//write the data on Ausgabe.dat
for (int i = 0; i < a; i++)
{
ausgabe << "(" << vecein[i] << "," << vecein1[i] << "," << Matrixein[i]<<")" << endl;
}
return 0;
}
it's written in German so I don't wonder about the variable names. My problem is that I don't really understand what I'm doing in the while loop. Zahlen.dat is a file similar to 1 2 3 4 5 6 7... and Ausgabe.dat is an empty file. Actually it does write in Ausgabe.dat because it tells me that the content has changed but when I reload the file it's still empty.
I've tried your advice but it still doesn't work. I did not change the way I read my datas because I wanted to see if it works first.
Here is my error message:
terminate called after throwing an instance of 'std::out_of_range'
what(): vector::_M_range_check: __n (which is 10) >= this->size() (which is 10)
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
My code looks like this right now:
int main()
{
ifstream einlesen ("Zahlen.dat");
if (einlesen)
cout<<"Daten wurden eingelesen"<<endl;
else
{
cout<<"Konnte Daten nicht einlesen"<<endl;
return 99;
}
double a;
int n{0};
while ( einlesen >>a>>a>>a>>a>>a>>a>>a) n++;
{
einlesen.clear();
einlesen.seekg(0, ios_base::beg);
vector<double> vecein(n), vecein1(n),Matrixein(n);
int b;// new variable of type int.
for (b = 0;b<n;b++);
{
einlesen>>vecein.at(b);
einlesen>>vecein1.at(b);
einlesen>>Matrixein.at(b);
}
ofstream ausgabe ("Ausgabe.dat");
for (int i = 0; i < b; i++)
{
ausgabe << "(" << vecein[i] << "," << vecein1[i] << "," << Matrixein[i] <<")" << endl;
}
}
return 0;
So I basically only changed the variable of the loop.
Yes the programm did work when I used to get the Data with cin.
I really have no idea why the programm is not working!
There are several things in the first code sample that should be done differently. The program first opens the file, and counts the number of blocks of 7 numbers in the file in variable n. Then the file pointer is reset, three vectors are created with a size of n, and the first n numbers are read into the vector from the file. But: You don't have to know the number of entries in a vector beforehand, so there is no need to read the file twice. Just use vector::push_back to add the numbers.
Second problem: In the loop to read the numbers, a is used as the loop variable, which is a double. The incrementing of a double could result in a one-off error, thus explaining your crash.
I'm also not sure the logic is correct: It seems you expect the file to have several (n) lines of numbers with 7 numbers each, but you then read the first n numbers. Say you have 10 lines, then you read the first line and three numbers of the second line into your vectors, also you might have wanted to read all numbers or maybe the first of each line (or even a 3d structure).
What about the second code sample, where you read from cin? Did that one work? It might help if you explained what you are trying to do, it seems there are vectors in the file, that you want to take the vector product (Kreuzprodukt) of? What is their layout in the file, are they written in lines or columns?
EDIT: The cause for the crash seems to be this line:
for (a = 0;a<n;a++);
{
einlesen>>vecein.at(a);
...
Notice the ; after the loop. This causes the loop to first run without any statement, and the part within brackets runs afterwards, when the loop condition is no longer fulfilled, i.e. a is already equal to n.

C++ vector memory access issue

I have a vector with a list of commands as shown below:
//COMMAND INITIALISATION
std::vector<std::string> objectInitialisationAction;
objectInitialisationAction.push_back("CREATE"); //0
objectInitialisationAction.push_back("END_CREATE"); //1
objectInitialisationAction.push_back("START_TIMELINE"); //2
I only access this vector by using my function shown below:
int SearchFor(std::string search, std::vector<std::string> from)
{
int result=-1;
for(int i=0; i<from.size(); i++)
if(from[i]==search)
{
result=i;
break;
}
if(result == -1)
{
std::ofstream error("searching.txt");
error<<"search failed, original value = \""<<search<<"\""<<std::endl;
error<<"values in the table:"<<std::endl;
for(int i=0; i<from.size();i++)
error<<"value "<<i<<": "<<from[i]<<std::endl;
error.close();
}
return result;
}
With only one function call:
commandNum=SearchFor(command[0], objectInitialisationAction);
This is the only place where I access the vector, yet when I call the function for the nth time (it always brakes at the same point in the code) it accesses wrong and outputs gibberish. Some of the code I list below:
search failed, original value = "CREATE"
values in the table:
value 0: CREATE Øç¼ Œ Ôç¼ Œ Ðç¼ Exit ¼ç¼ ¸ç¼ Œ  p«üxðù ; ´ç¼ Œ pëù#òø €< °ç¼ ŒBerlin Sans FB Demi e ¬ç¼ ˆ°¿^nmra œç¼ ŒBerlin Sans FB Demi e ˜ç¼ help ”ç¼ ˆ  object_dump ç¼ test Œç¼ Ž spawn ˆç¼ ‹ load_map „ç¼ Ž
//and so on...
Any suggestions as to why a vector may corrupt like that?
It seems all correct. Compile and execute this. If it is all correct probably the problem is in another part of your code.
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
int SearchFor(std::string search, std::vector<std::string> from)
{
int result=-1;
for(unsigned int i=0; i<from.size(); i++)
if(from[i]==search)
{
result=i;
break;
}
if(result == -1)
{
std::ofstream error("searching.txt");
error<<"search failed, original value = \""<<search<<"\""<<std::endl;
error<<"values in the table:"<<std::endl;
for(unsigned int i=0; i<from.size(); i++)
error<<"value "<<i<<": "<<from[i]<<std::endl;
error.close();
}
return result;
}
int main()
{
std::vector<std::string> objectInitialisationAction;
objectInitialisationAction.push_back("CREATE"); //0
objectInitialisationAction.push_back("END_CREATE"); //1
objectInitialisationAction.push_back("START_TIMELINE"); //2
for(unsigned int i=0; i<objectInitialisationAction.size(); i++)
{
cout<< objectInitialisationAction[i] << endl;
}
cout << "FOUND " << SearchFor("CREATE", objectInitialisationAction);
return 0;
}
I suggest you to add using namespace std; at the beginning of the file, so you have not to add std::blablabla on each declaration...your code will be more readable :) and please....INDENT IT :)
Your code looks correct to me. In this case, there should be another part of your application that corrupts the memory. For example, there could be an out-of-range array access, a dangling pointer or a use-after-delete somewhere. Tools like Valgrind might help you here.
The code looks ok as it is. The most likely scenario for me is that the length field of your strings gets unintentionally overwritten, because the command, i.e. the actual data, is still there. It's just that the string thinks it's longer than that. (Overwriting the characters wouldn't lead to the output you report: The commands would be overwritten, but the string length would still be short.) Overwriting memory typically happens through an array index or pointer which is out of bounds. The data it points to must have the same linkage as the strings (in your example local or global/static).
One strategy for bug searching would be to occasionally print the length of objectInitialisationAction's element strings; if they are too long you know something went wrong.
It may help to comment out code using a kind of binary search strategy (comment out one half -- mocking it's functionality to keep the prog running -- and look whether the error still occurs, then divide the faulty part again etc.).
Note that you pass the vector by value into SearchFor() which is perhaps unintended. The corruption may happen at the caller's or callee's side which should be easy to test.--
Hoped that helped.
try to pass all params through const refs:
int SearchFor(const std::string& search, const std::vector<std::string>& from)
{
...
}

Im trying to make a program that just displays the tiles 2 players would start with in Scrabble, but it keeps crashing?

I have this program I am working on that is similar to scrabble. This program below is a "mini-program" however, it should just be able to print out the 7 starting tiles for the two players. This mini-program seems like it should be fully operational, but it just crashes. Do you guys have an ideas as to why it doesnt run. Thanks so much for your time! :D
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include <cctype>
using namespace std;
void selectTiles(char (*lettArray)[53], char (*playPieces)[8], char (*compPieces)[8])
{
int pP1, pP2, pP3, pP4, pP5, pP6, pP7;
int cP1, cP2, cP3, cP4, cP5, cP6, cP7;
//0000000
srand(time(NULL));
rand();
pP1=rand()%53;
(*playPieces)[0]=(*lettArray)[pP1];
strcpy((lettArray)[pP1],"*");
do{
pP2=rand()%53;
(*playPieces)[1]=(*lettArray)[pP2];
}while(strcmp((lettArray)[pP2],"*")==0);
do{
pP3=rand()%53;
(*playPieces)[2]=(*lettArray)[pP3];
}while(strcmp((lettArray)[pP3],"*")==0);
do{
pP4=rand()%53;(*playPieces)[3]=(*lettArray)[pP4];
}while(strcmp((lettArray)[pP4],"*")==0);
do{
pP5=rand()%53;(*playPieces)[4]=(*lettArray)[pP5];
}while(strcmp((lettArray)[pP5],"*")==0);
do{
pP6=rand()%53;(*playPieces)[5]=(*lettArray)[pP6];
}while(strcmp((lettArray)[pP6],"*")==0);
do{
pP7=rand()%53;(*playPieces)[6]=(*lettArray)[pP7];
}while(strcmp((lettArray)[pP7],"*")==0);
do{
cP1=rand()%53;(*compPieces)[0]=(*lettArray)[cP1];
}while(strcmp((lettArray)[cP1],"*")==0);
do{
cP2=rand()%53;(*compPieces)[1]=(*lettArray)[cP2];
}while(strcmp((lettArray)[cP2],"*")==0);
do{
cP3=rand()%53;(*compPieces)[2]=(*lettArray)[cP3];
}while(strcmp((lettArray)[cP3],"*")==0);
do{
cP4=rand()%53;(*compPieces)[3]=(*lettArray)[cP4];
}while(strcmp((lettArray)[cP4],"*")==0);
do{
cP5=rand()%53;(*compPieces)[4]=(*lettArray)[cP5];
}while(strcmp((lettArray)[cP5],"*")==0);
do{
cP6=rand()%53;(*compPieces)[5]=(*lettArray)[cP6];
}while(strcmp((lettArray)[cP6],"*")==0);
do{
cP7=rand()%53;(*compPieces)[6]=(*lettArray)[cP7];
}while(strcmp((lettArray) [cP7],"*")==0);
//0000000
}
int main()
{
char lettArray[53]="AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSTTUUVVWWXXYYZZ";
char (*pLetters)[53]=&lettArray;
char player[8];
char (*pPlayer)[8]=&player;
char computer[8];
char (*pComputer)[8]=&computer;
selectTiles(pLetters,pPlayer,pComputer);
for (int i=0;i<53;i++)
cout<<"|"<<lettArray[i]<<"|";
cout<<endl;
for (int i=0;i<8;i++)
cout<<"|"<<player[i]<<"|";
cout<<endl;
for (int i=0;i<8;i++)
cout<<"|"<<computer[i]<<"|";
cout<<endl;
system("pause");
}
I compiled this program on g++ version 4.5.3 under Cygwin and, after changing #include <string> to #include <cstring> it compiled and ran without apparent problem.
However, when I looked at the output, it was clear that the program was writing 8 letters instead of 7 for each player's Scrabble letters and the last letter in each set was from a previously unallocated piece of memory.
Thus, I'd suggest the lines like:
for (int i=0;i<8;i++)
... should be:
for (int i=0;i<7;i++)
There might well be other errors that I haven't spotted yet.
(EDIT)
The line:
for (int i=0;i<53;i++)
... also prints an extra character. It should be:
for (int i=0;i<52;i++)
Also, amplifying Beta's point on the use of strcpy, strcpy(dest,"*") will copy two characters to the address pointed to by dest, not one character. That is, it will copy "*" and the null that terminates the string. That will probably overwrite data that was not intended to be overwritten with the null.
I think the problem is here:
void selectTiles(char (*lettArray)[53], ...)
{
...
pP1=rand()%53;
strcpy((lettArray)[pP1],"*");
...
}
That strcpy is not doing what you think it's doing. It's (usually) writing out of bounds and causing undefined behavior. Use std:string instead of char [], references instead of pointers, and test your code as you develop it, and you won't have these problems.
EDIT:
All right, first let's tidy up the code so we can see what we're doing. All of those copy-and-pasted do-while loops in selectTiles(...) are painful to look at. Step 1, we introduce a new function for drawing a random character from lettArray:
char draw(char *lettArray)
{
int pp;
do{
pp=rand()%53;
}while(lettArray[pp]=='*');
return(lettArray[pp]);
}
void selectTiles(char (*lettArray)[53], char (*playPieces)[8],
char (*compPieces)[8])
{
int pP1;
//0000000
srand(time(NULL));
rand();
pP1=rand()%53;
(*playPieces)[0]=(*lettArray)[pP1];
strcpy((lettArray)[pP1],"*");
(*playPieces)[1]=draw(*lettArray);
(*playPieces)[2]=draw(*lettArray);
(*playPieces)[3]=draw(*lettArray);
(*playPieces)[4]=draw(*lettArray);
(*playPieces)[5]=draw(*lettArray);
(*playPieces)[6]=draw(*lettArray);
(*compPieces)[0]=draw(*lettArray);
(*compPieces)[1]=draw(*lettArray);
(*compPieces)[2]=draw(*lettArray);
(*compPieces)[3]=draw(*lettArray);
(*compPieces)[4]=draw(*lettArray);
(*compPieces)[5]=draw(*lettArray);
(*compPieces)[6]=draw(*lettArray);
//0000000
}
This alone reduces the length of the code by 30 lines and makes it much easier to read. It also underscores the silliness of passing pointers to arrays. In C an array is passed as a pointer to the first element, so no further indirection is necessary. And since (in selectTiles) lettArray is a pointer to a char[], this line:
strcpy((lettArray)[pP1],"*");
is deadly. If pP1 is, say, 12, you're not putting an asterisk at the twelfth (or thirteenth) position in the array, you're copying "*" into the twelfth char array past the real one. That is, you're writing out of bounds. Let's correct the line (and put in some for loops):
pP1=rand()%53;
(*playPieces)[0]=(*lettArray)[pP1];
(*lettArray)[pP1]= '*';
for(int k=1 ; k<7 ; ++k)
(*playPieces)[k]=draw(*lettArray);
for(int k=0 ; k<7 ; ++k)
(*compPieces)[k]=draw(*lettArray);
And the code stops crashing. There's still a lot of improvement possible, but now it works.

work with .hpp files

The codes in my main program are given below; here I read a file called test.dat and data of this file put in to my structure so for that I used a class called MyData (my_data.hpp).
int main()
{
// cout<<"this my program"<<endl; // when this delete, this codes are not working
bool ok=true;
MyData my_data("test.dat", ok);
if(ok==false){
cout<<"Error, unable to read file1.";
return 0;
}
ACalculation a_calculation(&my_data);
For the calculation part, I used another class, AClaculation (a_calculation.hpp). Here I used pointers to speedup my program.
ACalculation (MyData * my_data){
MYData::iterator i;
for (i= my_data ->begin(); i!= my_data ->end(); i++){
if(i->A() > max){
max = i->A();
}
}
cout<<”my max value is:”<<max;
My program does not show any errors but when I run it, it does not show the result of my max value. But when I added a “cout” code at the beginning of the main program then it shows the result. It means, when I delete this line:
cout<<""this my program";
the program does not show correct output. But when I add it again, it workq. I can't understand where the error of my program is?.
Please help me to find out my mistakes here.. thanks
I think you have to flush the console printing an endl

Making an array of pointers to structs or objects in C++

So I'm basically just trying to take in some file input, and then take that data and put it into several structs. The only issue I'm having is with the naming of the pointers to the structs. The struct's themselves are supposed to represent students and I wanted to set each pointer as one of their names rather than an arbitrary variable. I tried to do this in a way that I'm assuming is syntactically wrong for it didn't work. In the code below, I increment the for loop with the temp array because each 4th position is a new student. Any ideas on how I could go about this?
#include<iostream>
#include<iomanip>
#include"student.h"
#include"creditcard.h"
#include<fstream>
using namespace std;
int main ()
{
string creditcards[20];
int i;
int x;
int amount;
string temp[20];
ifstream infile;
string filename;
int count;
int numstudents;
string newstring="";
string pointers[20];
cout<<"enter the file name of which you've stored your"<<endl
<<"credit card infomation"<<endl;
getline(cin,filename,'\n');
infile.open(filename.c_str());
count=0;
getline(infile,temp[count],'\n');
while(! infile.eof())
{
count++;
getline(infile,temp[count],'\n');
numstudents= (count/4);
if(numstudents < 1 || count%4 != 0)
{
cout<<"incorrect data file"<<endl;
}
}
cout<<numstudents<<endl;
for(i=0,x=0; i<numstudents;i++,x+4)
{
student *temp[x];
temp[x] = new student;
pointers[i] = temp[x];
}
for(i=0;i<numstudents;i+4)
{
cout<<temp[i]<<endl;
}
return 0;
}
Ok, let's start from the top.
Your code was (before I reformatted it) a mess. Messy code is harder to read and more likely to have bugs.
You have 3 arrays, each containing 20 strings. Why do you need so many?
One of them is named temp; having to use that as a variable name is a good indicator that you're mishandling data somewhere.
You're declaring int count relatively early on, then initializing it to 0 later. While not necessarily a bad thing, that's not the best method (do both at once, when needed).
You can declare local variables more than one in a line, but you don't need to declare them all at the top of the function. That's not necessary in C++.
int main ()
{
string creditcards[20];
int i = 0, x = 0, amount = 0;
(legal, but might not be needed)
It's typically better to declare and initialize a variable at the same time, just before you need it:
int count = 0;
getline(infile, temp[count], '\n');
I remember seeing that reading until you hit eof isn't recommended, although I'm not entirely sure on that. You may want to change this:
while ( !infile.eof() )
{
Now, the first actual mistake I see here is that you read a line, increment count, then read another line before acting. Is that intentional, and if so, why is it necessary? Doing the getline and increment inside the loop would be more readable and potentially more reliable.
count++;
getline(infile, temp[count], '\n');
This line is a bug, I think:
for(i=0,x=0; i<numstudents;i++,x+4)
The last section does i++, x+4. It does not change x.
The next loop after that handles i in the same way this loop uses x, so you can probably combine those two.
Now, on top of all that, massive temp arrays are not the solution to this problem (or any other that I can think of).
To store this kind of data, you'll want to look into a std::map<std::string, student*> or std::vector<student*>. The vector will allow you to push the new student struct to the back when necessary, and the map will allow you to key them based on name and retrieve that later, something like so:
typdef map<string, student*> studentmap;
studentmap students;
studentmap::iterator iter = students.find("Bob");
if ( iter != students.end() )
{
student * bob = iter->second;
// Work with data
}
It's a much better way of handling this, and will take a lot of the guess work out of what you're doing now.
If you want to be able to reference the students by name, consider using a map<string, student> or map<string, student*>.
This will allow you to refer to individual students via students["Jack"] or students["Jill"].