C question! I have a .txt file with this info:
james, watson
brittany,blake
roger,tra4@pos
jonathan, pote5
amber,Trisa123!
where the first columnn is name and the second one is the Id of website users.
I need to read this file and then sotre the informations into 2 arrays: name[] user_Id [] could you please help me? I found the solution for saving it into a 2d vector but I prefer to save it as arrays since I need to compare the string values with another string (received by uer to check if her name/user Id is already in the system or not)
I found the solution for saving it into a 2d vector but not for arrays.
CodePudding user response:
I will show you your requested solution, but I am sorry to inform you that the solution approach is wrong. For various reasons. First, and most important: In C C-Style arrays should in general not not be used.
C-Style arrays have fixed size and are not dyanmic. So, you will always come up with a magic number of an estimated max size. The correct approach would be to use a dynamic container. And for your solution, the std::vector
is most appropriate.
Then, it is a very bad idea to have to separate arrays for related data. The correct approach is to put related data in a struct
and then create a std::vector
of this struct. Otherwise you will have always to maintain and handle always 2 arrays, and you may even lose the sync between related data.
Anyway, I will first show you a solution following your idea:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
using namespace std;
const unsigned int MagicNumberForMaxArraySize = 42;
int main() {
// Define Arrays to hold the user and their IDs
string user[MagicNumberForMaxArraySize]{};
string user_ID[MagicNumberForMaxArraySize]{};
// Open the file and check, if it could be opened
ifstream ifs("test.txt");
if (ifs.is_open()) {
unsigned int index = 0;
// Read all lines and put result into arrays
while ((index < MagicNumberForMaxArraySize) and
(getline(getline(ifs, user[index], ',') >> ws, user_ID[index]))) {
// Now we have read a comlete line. Goto next index
index;
}
// Show debug output
for (unsigned int i = 0; i < index; i)
cout << "User: " << user[i] << "\tID: " << user_ID[i] << '\n';
}
else
cout << "\n\n*** Error: Could not open source file\n\n";
}
But I would not recommend to go on with that. The next improvement would be to use a struct
and then an array of struct. Additionaly, I will get rid of using namespace std;
which should never be used. And, I initialize varaibles with the universal initializer.
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
const unsigned int MagicNumberForMaxArraySize = 42;
struct Data {
std::string user{};
std::string ID{};
};
int main() {
// Define array for our needed data
Data data[MagicNumberForMaxArraySize];
// Open the file and check, if it could be opened
std::ifstream ifs("test.txt");
if (ifs.is_open()) {
unsigned int index = 0;
// Read all lines and put result into arrays
while ((index < MagicNumberForMaxArraySize) and
(std::getline(std::getline(ifs, data[index].user, ',') >> std::ws, data[index].ID))) {
// Now we have read a comlete line. Goto next index
index;
}
// Show debug output
for (unsigned int i = 0; i < index; i)
std::cout << "User: " << data[i].user << "\tID: " << data[i].ID<< '\n';
}
else
std::cout << "\n\n*** Error: Could not open source file\n\n";
}
Evolution:
We will now introduce an object oriented principle . Data and methods operating on this data shall be in one class
or struct
. Hence, we will add IO methods to the struct
, and add an aditional struct
for holding all users. Also, the new if
-statement with initializer can be used. And of course the std::vector
.
Please see:
#include <iostream>
#include <fstream>
#include <string>
#include <iomanip>
#include <vector>
// Struct to hold properties for one user
struct User {
std::string name{};
std::string ID{};
// Simple extraction
friend std::istream& operator >> (std::istream& is, User& user) {
std::getline(std::getline(is, user.name, ',') >> std::ws, user.ID);
return is;
}
// Simple inserter
friend std::ostream& operator << (std::ostream& os, const User& user) {
return os << "User: " << user.name << "\tID: " << user.ID;
}
};
// This class will contain all users
struct Data {
std::vector<User> users{};
// Simple extraction
friend std::istream& operator >> (std::istream& is, Data& d) {
// Delete potential existing old data
d.users.clear();
// Now read all users
for (User temp{}; is >> temp; d.users.push_back(std::move(temp)));
return is;
}
// Simple inserter
friend std::ostream& operator << (std::ostream& os, const Data& d) {
for (const User& u : d.users) os << u << '\n';
return os;
}
};
int main() {
// Open the file and check, if it could be opened
if (std::ifstream ifs("test.txt");ifs) {
// Read all data and show result
if (Data data{}; not (ifs >> data).bad())
std::cout << data;
}
else
std::cout << "\n\n*** Error: Could not open source file\n\n";
}
CodePudding user response:
You can also use strtok()
from cstring
library to split string into tokens: Split string in C/C