Mainly technical problems:
One difference from your code is the the vector part which I thought is a structure containing course_abbreviation, credit and grade. Yours is a vector of string. Which is the part I did not catch with your code?
code:
Code:
#include <iostream>
#include <fstream>
#include <string>
#include <cstring>
#include <map>
#include <vector>
#include <cstdlib>
using namespace std;
struct grades {
string course_Abrrev;
int course_Credit;
char course_Grade;};
struct IDnName {
int student_ID;
string student_Name;};
int main(int argc, char *argv[])
{
vector <struct grades> Courses;
map < string, vector < grades > >marks;
map < string, string > names;
ifstream inFILE;
inFILE.open(argv[1]);
if (inFILE.fail()) {
cout << "ERROR: File failed to open!" << endl;
} else {
string line; //string for one line
struct IDnName oneName; // Allocate a place for one ID and name
struct grades oneCourse; // Allocate a place for a structure for a record of one course
while (inFILE.good()) {
char *sPtr; //string pointer for token
char *sArray = new char[line.length() + 1]; //Initialize pointer sArray for string--->char* conversion
getline(inFILE, line); //Read the whole line
strcpy(sArray, line.c_str());
//tokenize the line into array
sPtr = strtok(sArray, " ");
// oneName.student_ID = atoi(sPtr[0].c_str());// did not work
oneName.student_ID = stoi(sPtr); //c++ method
while (sPtr != NULL) {
oneName.student_Name = sPtr;
names.insert(make_pair(oneName.student_ID, oneName.student_Name)); //LINE 54
sPtr = strtok(NULL, " ");
oneCourse.course_Abrrev = sPtr;
sPtr = strtok(NULL, " ");
// oneCourse.course_Credit = atoi(sPtr[0].c_str());// did not work
oneCourse.course_Credit = stoi(sPtr);
sPtr = strtok(NULL, " ");
oneCourse.course_Grade = sPtr[0];
}
if (marks.find(oneName.student_ID) != marks.end()) { //LINE 65 marks.insert(make_pair(oneName.student_ID, vector<struct grades>())); //LINE 66
} else {
Courses.push_back(oneCourse);
}
}
}
// print part not ready yet
return 0;
}
Highlighted LINE 54, 65 & 66 are the parts throwing out lots of errors. Thanks!
That wasn't what I meant by using pairs, but I think you'd do map.insert( std::pair<type,type>(valuea, valueb) )
The reason your 'atoi' didn't work is because you're trying to call c_str on something that's already a c string! atoi(sptr); stoi is just an alias to atoi on systems that have it(unlike mine, which did not.) Use atoi.
That 'courses' structure doesn't look useful for anything, not sure why you have it, all the information is in 'marks'.
Finally -- I think you missed the point. Imagine how they make these map<>'s, it's going to be a list or array of some kind internally, right? So in memory somewhere there is a structure like this:
This isn't just wasted memory, it creates the opportunity for your program to store "impossible" states where element.key.studentid and element.value.studentid disagree. This seems even more likely to happen when keeping the same value around in different places as different types!
So:
Use studentid as an integer everywhere.
Never duplicate your key inside your data, only use it to fetch your data.
Thanks! Courses is a vector of struct, which seems needed as (map) value of marks. It is to hold the grades structures when more courses are pushed into the vector until eof. So the vector sizes are very likely different for each student. In the example input file, there are 3 students that have 3, 4 and 5 courses, respectively.
like:
Your program is a mess, had no error checking and crashed nonstop. That's why strtok is considered "evil" -- if you don't bother checking, bad things will happen. But a little checking makes it fine.
Nearly every line ended up commented out and replaced, I had to rewrite it instead.
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h> // You need this for atoi, see 'man atoi'
#include <map>
#include <vector>
#include <string>
using namespace std;
struct grades {
string course_Abrrev;
int course_Credit;
char course_Grade;
};
int main(void)
{
char buf[4096];
map<int, string> names;
map<int, vector < grades > > marks;
// Read a line into 'buf'
while(fgets(buf, 4096, stdin) != NULL)
{
// Array of 10 pointers.
// Each will point to a position inside 'buf', or
// just point to "".
const char *token[10];
grades grade;
int n=0;
token[n]=strtok(buf, " \r\n\t");
while(n < 10)
{
n++;
token[n]=strtok(NULL, " \r\n\t");
if(token[n]==NULL) break;
}
// Set all NULL strings to "" instead.
while(n < 10) token[n++]="";
// There, now we have a nice array of tokens
// which are all guaranteed not to crash when used.
// The very worst any of them will be is blank...
n=atoi(token[0]); // Get student ID
grade.course_Abrrev=token[2];
grade.course_Credit=atoi(token[3]);
grade.course_Grade=*(token[3]);
names[n]=token[1]; // Store name
marks[n].push_back(grade); // store grade
}
for(map<int, string>::iterator i=names.begin();
i != names.end();
i++)
{
int id=(*i).first;
printf("%d %s\n", id, (*i).second.c_str());
for(vector<grades>::iterator n=marks[id].begin();
n != marks[id].end();
n ++ )
{
printf("\t%s %d %c\n",
(*n).course_Abrrev.c_str(),
(*n).course_Credit,
(*n).course_Grade);
}
}
}
Courses is a vector of struct, which seems needed as (map) value of marks. It is to hold the grades structures when more courses are pushed into the vector until eof.
Why? A vector can hold as many as you want already, and if you want to know how large it is, just ask: (something).size()
Logically I was thinking in a totally different way! Definitely I missed many points that may be critical for programming. Let me try out your code first. Thanks a lot!
In AWK
For 3 individual vectors of the form:
-2.772 -9.341 -2.857
-5.140 -6.597 -1.823
-2.730 -5.615 1.159
I would like to write a script that parses line by line to (i) normalise, (ii) divide by the norm for *each* vector.
I.e.
sqrt(-2.772^2 + -9.341^2 + -2.857^2)=10.154
... (4 Replies)
hello guys.
i'm new to c++. i've problem using two dimensional vector.
i've a project of making conway's game of life. this is the code that i have made so far.
my problem is how can i give a two dimensional vector through main.
glider.vec1 = vec; is not correct way to give a two... (2 Replies)
Hi all, from my understanding I understand that I can use array in this manner.
struct test
{
int a;
int b;
int c;
};
test testing; //creating an array with the structer type
testing.a=1;
testing.b=2;
testing.c=3;
If I'm not wrong we can use array in this manner,... (12 Replies)
Hi,
I have received an application that stores some properties in a file. The existing struct looks like this:
struct TData
{
UINT uSizeIncludingStrings;
// copy of Telnet data struct
UINT uSize;
// basic properties:
TCHAR szHost; //defined in Sshconfig
UINT iPortNr;
TCHAR... (2 Replies)
Hi, I've used the following way to set ssh public key authentication and it is working fine on Solaris 10, RedHat Linux and SuSE Linux servers without any problem. But I got error 'Server refused our key' on Solaris 8 system. Solaris 8 uses SSH2 too. Why? Please help. Thanks.
... (1 Reply)
I modified some code I found on Wikipedia concerning maps to see if it would work before applying it to a project I'm working on that has a similar idea.
What I would want is for a user to be able to enter sentences and then be able to distinguish how many times a the person entered a word in a... (4 Replies)
Can someone tell me how to do this?
Just a thought that entered my mind when learning about structs.
First thought was:
struct one
{
struct two;
}
struct two
{
three;
}
one->two->three
would this be how you would access "three"? (1 Reply)
Hi
i have the following structure
struct S
{
char Mod_num;
char val;
char chr_nm_cd;
}
I am reading a 2GB file and inserting into the structure and writing into a vector.
I feel like only vector will be a right option. I tried with multimap but it is memory intensive and hence i... (1 Reply)