I have a text with this format:
NAME(char) ID(int) MARK(int)
for example:
JOSH 1234 100
SARA 5678 90
..
..
I want to read this file, enter the params to a students struct and then print it on the screen ( you can see in the code).
My problem is that it seems I can't read the name properly, and this line:
while (file >> id >> word >> grade) - is getting the id and the mark correct, but the name in the variable word (which is char *) is getting hex addresses like 0x000a8520.
#include <iostream>
#include <fstream>
#include <cstring>
using namespace std;
struct Student
{
int id;
char * name = new char [25];
int mark;
};
int makeStudentsArr(Student * ptr, char * address);
void printArr(Student * ptr, int number);
int main() {
char * address = new char[26];
Student * myptr = new Student[50];
cin >> address;
int count;
count = makeStudentsArr(myptr, address);
printArr(myptr, count);
system("pause");
return 0;
}
int makeStudentsArr(Student * ptr, char * address) {
ifstream file;
file.open(address);
char * word = new char[25];
int id,grade;
int index = 0;
while (file >> id >> word >> grade) {
ptr[index].id = id;
ptr[index].name = word;
ptr[index].mark = grade;
index++;
}
return index;
}
void printArr(Student * ptr, int number) {
for (int i = 0;i < number;i++) {
cout << "name: " << (ptr + i)->name << " id: " << (ptr + i)->id << " mark: " << (ptr + i)->mark << endl;
}
}
Change this:
ptr[index].name = word;
to this:
strcpy(ptr[index].name, word);
since the first copies the pointer, while the second copies the actual string (where the pointer is pointing to)!
However, your program does not delete the memory you dynamically allocated with new, which results in memory leaks.
It would be much easier if you used an std::string instead of C strings. Moreover, it would also be easier, if you used an std::vector instead of plain C arrays.
Related
I was taught that you have to use gets(str) to input a string and not cin. However I can use cin just fine in the program below. Can someone tell me if you can use cin or not. Sorry for my bad English. The program lets you insert 5 names and then print those names to the screen.
Here's the code:
#include <iostream>
#include <string.h>
using namespace std;
int main()
{
char **p = new char *[5];
for (int i = 0; i < 5; i++)
{
*(p + i) = new char[255];
} //make a 2 dimensional array of strings
for (int i = 0; i < n; i++)
{
char n[255] = "";
cout << "insert names: ";
cin >> n; //how i can use cin here to insert the string to an array??
strcpy(p[i], n);
}
for (int i = 0; i < n; i++)
{
cout << p[i] << endl; //print the names
}
}
You can indeed use something like
std::string name;
std::cin >> name;
but the reading from the stream will stop on the first white space, so a name of the form "Bathsheba Everdene" will stop just after "Bathsheba".
An alternative is
std::string name;
std::getline(std::cin, name);
which will read the whole line.
This has advantages over using a char[] buffer, as you don't need to worry about the size of the buffer, and the std::string will take care of all the memory management for you.
Use ws (whitespace) in getline() like getline(cin>>ws, name);
If numeric input is before the string then due to whitespace the first string input will be ignored. Therefore use ws like getline(cin>>ws, name);
#include <iostream>
using namespace std;
main(){
int id=0;
string name, address;
cout <<"Id? "; cin>>id;
cout <<"Name? ";
getline(cin>>ws, name);
cout <<"Address? ";
getline(cin>>ws, address);
cout <<"\nName: " <<name <<"\nAddress: " <<address;
}
I am making a program keeping track of different persons, which I try to read in from a file. I use a constructor that takes an ifstream file as an argument, and I then try to read in the data from the file. I can read the first line, which is just an int (a unique number for each person), but when I try to go to the next line and getline it, the program hangs. Does anyone know why?
#include <iostream>
#include <fstream>
#include <cstring>
#include <cctype>
#include <cstdlib>
using namespace std;
const int MAXPERS = 100;
const int MAXTXT = 80;
const int DATELEN = 7;
class Person {
private:
int nr;
char* firstName;
char birthDate[DATELEN];
public:
Person() {
char fname[MAXTXT];
cout << "First name: "; cin.getline(fname, MAXTXT);
firstName = new char[strlen(fname) + 1];
strcpy(firstName, fname);
cout << "Birth date (DDMMYY): ";
cin >> birthDate; cin.ignore();
}
Person(int n, ifstream & in) {
nr = n;
char fname[MAXTXT];
cin.getline(fname, MAXTXT);
firstName = new char[strlen(fname) + 1];
strcpy(firstName, fname);
in >> birthDate;
}
void display() {
cout << "\nFirst name: " << firstName;
cout << "\nBorn: " << birthDate;
}
void writeToFile(ofstream & ut) {
ut << firstName << "\n" << birthDate;
}
};
void readFromFile();
Person* persons[MAXPERS + 1];
int lastUsed = 0;
int main() {
readFromFile();
persons[1]->display();
return 0;
}
void readFromFile() {
ifstream infile("ANSATTE.DAT");
if(infile) {
while(!infile.eof() && lastUsed < MAXPERS) {
int nr;
infile >> nr;
persons[++lastUsed] = new Person(nr, infile);
}
}
}
My file looks like this:
1
Andy
180885
2
Michael
230399
In your constructor you have
cin.getline(fnavn, MAXTXT);
So your program is waiting for you to type something in. If you meant to get the name from the file then you need
in.getline(fnavn, MAXTXT);
^^ ifstream object
You are also going to run into the issue of mixing >> with getline. You will need to add
infile.ignore(std::numeric_limits<std::streamsize>::max(), '\n')
after infile >> nr; in your while loop.
strlen(fname + 1) will be strlen(fname) - 1 if fname is one-character long or more and indeterminate if fname is zero-character long. It should be strlen(fname) + 1.
strlen(fnavn + 1) has the same issue and should be strlen(fnavn) + 1.
#include <iostream>
using namespace std;
#include "ReadString.h"
void main()
{
int i ;
int NumNames=5;
char ** pNames;
int MaxNum = 10;
int more(0);
pNames = new char *[NumNames];
cout << "Enter names" << endl;
This is the part where I am having trouble. I tried in different way but didn't work out. I tried to make a loop unless the first character is an 'Enter Key'.
while(cin.get()!='\n')
{
for (i = more; i < NumNames; i++)
{
cout << (i + 1) << ") ";
pNames[i] = ReadString();
more = NumNames;
NumNames +=NumNames
}
}
Replace manually allocated dynamic array with some container which can grow dynamically, for example std::vector:
std::vector<std::string> names;
std::string name;
// read the names
while (cin >> name) {
names.push_back(name);
}
The input file contains 14 state initials (TN,CA,NB,FL,etc..) that is to be rad into the array. The code below clears compiler but when i tell the program the filename it shoots out a bunch of blank spaces with two spaces containing some fuzz and a third contain a '#' symbol. i assume the problem is with my function not entirely sure what specifically though any help greatly appreciated!
input file set up with state initials one on top of the other:
TN
PA
KY
MN
CA
and so on
void readstate( ifstream& input, string []);
int main()
{
string stateInitials[14];
char filename[256];
ifstream input;
cout << "Enter file name: ";
cin >> filename;
input.open( filename );
if ( input.fail())
{
cout << " file open fail" << endl;
}
readstate ( input, stateInitials);
input.close();
return (0);
}
void readstate ( ifstream& input, string stateInitials[])
{
int count;
for ( count = 0; count <= MAX_ENTRIES; count++)
{
input >> stateInitials[count];
cout << stateInitials[count] << endl;
}
}
You are treating a character array as though it were a string array.
While you can hack put the strings next to each other inside the same char array, that is not the standard way it is done. Here is a modified version of your code, which creates one char[] to hold each initial.
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <string.h>
#define MAX_ENTRIES 14
using namespace std;
void readstate( ifstream& input, char* []);
int main()
{
char** stateInitials = new char*[14];
char filename[256];
ifstream input;
cout << "Enter file name: ";
cin >> filename;
input.open( filename );
if ( input.fail())
{
cout << " file open fail" << endl;
}
readstate ( input, stateInitials);
// After you are done, you should clean up
for ( int i = 0; i <= MAX_ENTRIES; i++) delete stateInitials[i];
delete stateInitials;
return (0);
}
void readstate ( ifstream& input, char* stateInitials[])
{
int count;
string temp_buf;
for ( count = 0; count <= MAX_ENTRIES; count++)
{
stateInitials[count] = new char[3];
input >> temp_buf;
memcpy(stateInitials[count], temp_buf.c_str(), 3);
cout << stateInitials[count] << endl;
}
}
my text is something like this
55<space>The User Input Sentence;
i got the 55 out via the code below and assigned that to a int variable via atoi
std::string stringKey = userInput.substr(0, 2);
but how to get the rest of the string and assign it to a string variable ????the code below
this is the complete code (haven't finished it yet)
#include <iostream>
#include <string>
#include <algorithm>
#include <iomanip>
#include <cmath>
using namespace std;
//FUnction Prototypes
string encrypt(string, int);
string decrypt(string source, int key);
int main(int argc, char *argv[])
{
string source;
string userInput;
int key;
int choice;
cout << "To encode a message type 1, to decode a message type 2: ";
cin >> choice;
if (choice == 1)
{
cout << "Enter the message to encode: ";
cin >> userInput;
std::string stringKey = userInput.substr(0, 2);
key = atoi(stringKey.c_str());
std::string source = userInput.substr(3);
encrypt(source, key);
}
/*decrypt(source, key);
cout << "Source: ";
getline(cin, source);
cout << "Key: ";
cin >> key;
cout << "Encrypted: " << decrypt(source, key) << endl;*/
system("pause");
}
string encrypt(string source, int key)
{
string Crypted = source;
for (int Current = 0; Current < source.length(); Current++)
Crypted[Current] = ((Crypted[Current] + key) - 32) % 95 + 32;
return Crypted;
}
string decrypt(string source, int key)
{
string Crypted = source;
for (int Current = 0; Current < source.length(); Current++)
Crypted[Current] = ((Crypted[Current] - key) - 32 + 3 * 95) % 95 + 32;
return Crypted;
}
Same way as you got first part. Check out std::string substr
string second = userInput.substr(3);
----------------EDIT------------------
If you give 55<space>The User Input Sentence as input, only first string will be read.
Use getline method to read entire input including spaces