Reading a text file [closed] - c++

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Here is what I have so far. The problem am having now is reading and inserting the strings of words I have in my text file named "word.txt" into the trie tree. I used the "void init()"function to test that the tree functions and it does but using the text file, thats where I don't know how to
any idea please
#include <iostream>
using namespace std;
#include <fstream>
#include <iomanip>
#include <string>
class TrieNode {
public:
// Initialize your data structure here.
TrieNode() {
value = 0;
for (int i=0;i<26;i++){
children[i] = NULL;
}
}
int value;
TrieNode* children[26];
};
class Trie {
private:
TrieNode*root;
int count;
public:
Trie() {
root = new TrieNode();
count = 0;
}
// Inserts a word into the trie.
void insert(string s) {
TrieNode *p = root;
long int len = s.size();
for (int i=0;i<len;i++){
int index = s[i] - 'a';
if (! p->children[index]){
p->children[index] = new TrieNode();
}
p = p->children[index];
}
count++;
p->value = count;
}
// Returns if the word is in the trie.
// -1 if not in trie and not prefix of anything in trie
// 0 if not in trie but is a prefix of something in trie
// 1 if in trie
int search(string key) {
TrieNode *p = root;
long int lenght = key.size();
for (int i=0;i<lenght;i++){
int index = key[i] - 'a';
if (p->children[index]){
p = p->children[index];
}
else{
return -1;
}
}
if (p->value!=0){
return 1;
}
else{
return 0;
}
}
};
//Game class using a tree
class GhostGame{
private:
string row;
ifstream fin;
string wordSoFar = "";
string Player1,Player2;
Trie Tree;
public:
void ReadFile(){
ifstream fin("word.txt");
while (!fin.eof()) { // read file till the end
fin>>row;
getline(fin,row);
cout << row << endl;
Tree.insert(row);
}
//fin.close();
}
void init(){
Tree.insert("ab");
Tree.insert("acd");
}
//start menu
void StartGame(){
init();
cout<<"========================="<<endl;
cout<<"Welcome to Ghost Game"<<endl;
cout<<"========================="<<endl;
//ReadFile();
while(Tree.search(wordSoFar)!=1){
cout<< "Player 1 Insert a letter => ";
cin>> Player1;
cout<<setw(60)<<"now = ["<< wordSoFar <<"]"<<endl;
wordSoFar +=Player1;
if(Tree.search(wordSoFar)==1){
cout<< "Player 2 Wins "<<endl;
break;
}
cout<< "Player 2 Insert a letter => ";
cin>>Player2;
cout<<setw(60)<<"now = ["<< wordSoFar<<"]"<<endl;
wordSoFar += Player2;
if(Tree.search(wordSoFar)==1){
cout<< "Player 1 Wins "<<endl;
break;
}
}
}};
// main driver
int main()
{
GhostGame G1;
G1.StartGame();
return 0;
}

Use regular expressions for such task, they are in header file <regex>. Some good tutorials on regex can be found in book Professional C++ (Wrox) for example.
For file reading use ifstream class from <fstream>.

Open file
using fgets or get line function read the file into temporary string
check first character... Make sure to use tolower, before comparing
void findString(char *filename, char ch)
{
char temp[100];
FILE *infile = fopen(filename, "rw");
while(infile != NULL)
{
fgets(temp,100,infile);
if(tolower(temp[0]) == ch)
cout << temp;
}
fclose(infile);
}

Related

Using a vector function on a node member

I'm writing a program in C++ where I take in a line from a txt file and stick it into a vector<string> data that is within a struct (I'm making a linked list of each individual line). Technically I have a loop set up that will break up the words from the sentence I'm taking in, and pushing them into the vector one by one.
The issue I've ran into is when I try getting the vector size via
int size;
size = current->data.size();
Current being a node. I get both an implicit conversion warning and a "Thread 1: EXC_BAD_ACCESS (code=EXC_I386_GPFLT)".
Can anyone explain where I am going wrong? Is it just not possible to code something like that? Should I just create a counter variable to keep track of how many words are being placed into the vector? And what would be the best programming practice to go about achieving this?
Here is my main() file
#include <iostream>
#include <fstream>
#include "SkipGram.hpp"
using namespace std;
int main() {
string file;
ifstream inFile;
vector<string> sentence;
string line;
SkipGram control;
int skip;
int gram;
cout << "Please enter file name:\n";
cin >> file;
inFile.open(file);
while(!inFile.is_open()){ //makes sure we get a working file
cout << "Error reading in file. Please try again.";
cin >> file;
inFile.open(file);
}
cout << "Please enter how many words you want skipped and the amount of grams:";
cin >> skip >> gram;
while(!inFile.eof()){
getline(inFile, line);
control.convert(line);
}
control.skipGramFunc(skip, gram);
control.printSkipGram();
return 0;
}
Here is my .hpp file
#include <stdio.h>
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class SkipGram{
public:
SkipGram();
void convert(string line);
void skipGramFunc(int skip, int gram);
void printSkipGram();
private:
typedef struct sentence{
vector<string> data;
vector<string> result;
int position;
sentence* next;
}* sentencePtr;
sentencePtr first;
sentencePtr current;
int amount;
};
Here is my .cpp file
#include "SkipGram.hpp"
using namespace std;
SkipGram::SkipGram(){
first = NULL;
current = NULL;
amount = 0;
}
void SkipGram::convert(string line){
// go word by word through sentence and create a vector out of it
// add into the sentence list
sentencePtr newSentence = new struct sentence;
if(first == NULL){
current = newSentence;
first = newSentence;
amount++;
newSentence->position = amount;
}else {
current = newSentence;
amount++;
newSentence->position = amount;
}
string word;
int length = line.length();
int i = 0;
int front = 0;
int temp;
while( i <= length){
temp = line.find(" ");
if( temp == -1){
break; //catches when sentence is done with
}
word = line.substr(front, temp);
newSentence->data.push_back(word);
temp++;
line = line.erase(front, temp);
} //END OF WHILE
}
void SkipGram::skipGramFunc(int skip, int gram){
// goes through word vector and rearranges them
if(gram == 1){
cout << "Need more than one gram!" << endl;
return;
}
if(skip == 0 || gram == 0){
cout << "Input cannot be 0!";
}
int size;
int temp;
int tempAmount = amount;
current = first;
skip++;
while( tempAmount != 0){ // while loop goes through all the sentences
size = current->data.size();
size = size - skip; // size here essentially becomes a marker to find out where to stop the loop
for(int i = 0; i < size; i++){ // for loop goes through all the words
for(int j = 0; j < gram; j++){ // this loop checks to see if we got the right number of grams
if(j == 0){ // are we on the first gram
current->result.push_back(current->data.at(i));
}else { // we want skipped gram
temp = i + skip;
current->result.push_back(current->data.at(temp));
} // END OF IF
}// END OF GRAM IF
current->result.push_back(",");
}//END OF WORD FOR
current = current->next;
tempAmount--;
}//END OF WHILE
}// END OF FUNCTION
void SkipGram::printSkipGram(){
int tempAmount = amount;
current = first;
while(tempAmount != 0){
int size = current->data.size();
for(int i = 0; i <= size; i++){
cout << current->data.at(i);
};
}//END OF WHILE
}
You never assign to next, but you do read it. Whereupon your program exhibits undefined behavior by way of accessing a value of uninitialized object.

To check if a string has all Unique Characters in C++ [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Am trying to find If a string has all Unique characters and below is my code, But I get the error "invalid types 'char[int]' for array subscript" in the if statement of the function Unique char, can anyone tell me how to correct this
#include <iostream>
#include<cstring>
using namespace std;
bool unique_char(char);
int main()
{
char s;
bool check;
cout << "Enter any string" << endl;
cin>>s;
check = unique_char(s);
if(check)
cout<<"there are no duplicates";
else
cout<<"the string has duplicates";
return 0;
}
// The if statement in this section has the error
bool unique_char(char s)
{
bool check[256] = {false};
int i=0;
while (s != '\0')
{
if (check **[(int) s[i]]**)
return false;
else
{
check[(int) s[i]] = true;
i++;
}
}
}
You need to pass char array rather than a single char.
int main()
{
char s[1000]; // max input size or switch to std::string
bool check;
cout << "Enter any string" << endl;
cin>>s;
check = unique_char(s);
if(check)
cout<<"there are no duplicates";
else
cout<<"the string has duplicates";
return 0;
}
bool unique_char(char* s)
{
bool check[256] = {false};
int i=0;
while (s[i] != '\0')
{
if (check[(int) s[i]])
return false;
else
{
check[(int) s[i]] = true;
i++;
}
}
return true;
}

Shifting an array of structs C++

I am quite new to c++ programming and data structures and really need some help. I am working on an assignment where I have a text file with 100 lines and on each line there is an item, a status(for sale or wanted), and a price. I need to go through the text file and add lines to an array of structs and as I add lines I need to compare the new information with the previously submitted information. If there is a line that is wanted and has a price higher than a previously input item that is for sale then the item would be removed from the struct and the array of structs shifted.
The place that I am having trouble is in actually shifting all the structs once a line that satisfies the condition is found.
My issue is that when I try to shift the array of structs using the second for loop nothing happens and I just get null structs and nothing seems to move.
Please if you guys can offer any help it would be greatly appreciated.
Below is the code of the text file and my current code.
#include<iostream>
#include<fstream>
#include <string>
#include <algorithm>
#include <sstream>
using namespace std;
struct items
{
string type;
int status;
int price;
} itemArray [100];
int main(int argc, char *argv[]) {
int x = -1;
//int chickenCount = 0;
int counter = 0;
int itemsSold = 0;
int itemsRemoved = 0;
int itemsForSale = 0;
int itemsWanted = 0;
string itemType;
int itemStatus = 0;
int itemPrice = 0;
int match = 0;
ifstream myReadFile( "messageBoard.txt" ) ;
std::string line;
//char output[100];
if (myReadFile.is_open()) {
while (!myReadFile.eof()) {
getline(myReadFile,line); // Saves the line in STRING.
line.erase(std::remove(line.begin(), line.end(), ' '), line.end());
//cout<<line<<endl; // Prints our STRING.
x++;
std::string input = line;
std::istringstream ss(input);
std::string token;
while(std::getline(ss, token, ',')) {
counter++;
//std::cout << token << '\n';
if (counter>3){
counter =1;
}
//cout << x << endl;
if (counter == 1){
itemType = token;
//cout<< itemType<<endl;
}
if (counter == 2){
if (token == "forsale"){
itemStatus = 1;
//itemsForSale++;
}
if (token == "wanted"){
itemStatus = 0;
//itemsWanted++;
}
//cout<< itemStatus<<endl;
}
if (counter == 3){
itemPrice = atoi(token.c_str());
//cout<< itemPrice<<endl;
}
//cout<<"yo"<<endl;
}
if (x >= 0){
for (int i = 0; i<100;i++){
if (itemArray[i].type == itemType){
//cout<<itemType<<endl;
if(itemArray[i].status != itemStatus){
if (itemArray[i].status == 1){
if(itemPrice>=itemArray[i].price){
itemsSold++;
match =1;
//itemArray[i].type = "sold";
for (int j=i; j<100-1;j++){
//cout<<j<<endl;
itemArray[j].type = itemArray[j+1].type;
itemArray[j].status = itemArray[j+1].status;
itemArray[j].price = itemArray[j+1].price;
}
i =i-1;
break;
}
}
if (itemArray[i].status == 0){
if(itemArray[i].price>=itemPrice){
itemsSold++;
match = 1;
//itemArray[i].type = "sold";
for (int j=i; j<100-1;j++){
//cout<<j<<endl;
itemArray[j].type = itemArray[j+1].type;
itemArray[j].status = itemArray[j+1].status;
itemArray[j].price = itemArray[j+1].price;
}
i=i-1;
break;
}
}
}
}
}
}
if (counter == 3 && match == 0){
itemArray[(x)].type = itemType;
itemArray[(x)].status = itemStatus;
itemArray[(x)].price = itemPrice;
}
match = 0;
// cout << itemArray[x].type << " " << itemArray[x].status<<" "<<itemArray[x].price<<endl;
}
for(int i=0;i<100;i++){
cout<<itemArray[i].type<< " "<<itemArray[i].status<<" "<<itemArray[i].price<<endl;
}
//cout<<itemArray[1].price<<endl;
cout << itemsSold<<endl;
}
myReadFile.close();
return 0;
}
text file: https://drive.google.com/file/d/0B8O3izVcHJBzem0wMzA3VHoxNk0/view?usp=sharing
Thanks for the help
I see several issues in the code, but without being able to test it, I think the main problem is that you always insert new elements at position 'x' which correspond to the currently line read from the file, without taking into account any shift of elements done. You should insert the new element at the first empty slot (or just overwrite the old element instead of shifting everything).
An other issue is that you do not initialize the status and price in your array.
The best way would be to rewrite the code by using more standard C++ features, for example:
replace the items structure by a class with a constructor defining default values
use object copy (there is no need to copy a struct element by element)
use standard C++ containers like a list (see http://www.cplusplus.com/reference/list/list/) which has insert and erase methods

C++ Storing Items in Array and Setting each Token

My name is Faith and I am a beginner programmer in C++. I am working on a project where I have to read in two file and be able to separate the items in each file to its own variable. The first file has two pieces of information separated by "," and the second has three pieces of information. So far, I think I've done well with reading the files and getting each line in the file. Also I've separated each item by "," now I am trying to store those items in its on variable. Please Help! I've tried starting this project over multiple times and this is the only method I know how to implement to do this.
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdlib.h>
using namespace std;
class Manufactuer{
string upcode;
string company_name;
public:
void setupcode(string value){
upcode= value; }
void setcompany_name(string value){
company_name= value; }
string getupcode(){ return upcode;}
string getcompany_name(){return company_name;}
};
class Products{
string product_num;
string quantity;
string product_name;
public:
void setproduct_num(string value){
product_num= value; }
void setproduct_name(string value){
product_name= value; }
void setquantity(string value){
quantity = value;}
string getproduct_num(){ return product_num;}
string getquantity(){return quantity;}
string getproduct_name(){return product_name;}
};
int main(int argc, const char * argv[]) {
//opens the csv file
std::ifstream mccodesfile;
std::ifstream salesfile;
mccodesfile.open("mccodes.csv");
if(!mccodesfile){// file couldn't be opened
cout<<"Failed: file could not be opened"<<endl<<"Press Enter to Close:";
cin.get();
return 0;
}else
cout<<"Successfully opened file!"<<endl;
salesfile.open("sales.csv");
if(!salesfile){// file couldn't be opened
cout<<"Failed: file could not be opened"<<endl<<"Press Enter to Close:";
cin.get();
return 0;
}else
cout<<"Successfully opened file!"<<endl;
Manufactuer* upccodes;
int count; //how many elements in the array
int size; //how large the array
count = 0;
size = 2;
upccodes= (Manufactuer*)malloc(size*sizeof(Manufactuer)); //Malloc dynamatically reserve memory for variable pointer
string line;
while (getline(mccodesfile,line)) {// Taking every line from the file and putting in the variable line
Manufactuer newcode = Manufactuer(); //creating a upcode object
istringstream ss(line);
string token; //setting up split values
bool haveReadUPCode = false;
while (getline(ss,token,',')){// Separated values by comma
if(!haveReadUPCode){
newcode.setupcode(token);
haveReadUPCode = true;
}else{
newcode.setcompany_name(token);
}
}
if (count == size){
size = size * 2;
upccodes= (Manufactuer*)realloc(upccodes,size*sizeof(Manufactuer)); //Double the size while keeping the same elements
}
upccodes[count++]= newcode;
// cout<<line<<endl;
}
for (int i = 0; i<count; i++){
// cout<<upccodes[i].getcompany_name()<<endl; //Prints Manufactuers name--Works!
}
for (int i=0; i<count; i++) {
// cout<<upccodes[i].getupcode()<<endl; //Prints UPCcodes--Works
}
Products* product;
product= (Products*)malloc(size*sizeof(Products)); //Malloc dynamatically reserve memory for variable pointer
while(getline(salesfile, line)){{// Taking every line from the file and putting in the variable line
Products newProduct = Products(); //creating a product object
istringstream ss(line);
string token; //setting up split values
bool haveReadProduct = false;
while (getline(ss,token,',')){// Separated values by comma
if(!haveReadProduct){
newProduct.setproduct_num(token);
haveReadProduct = true;
} else{
newProduct.setproduct_name(token);
newProduct.setquantity(token);
}
}
if (count == size){
size = size * 2;
product= (Products*)realloc(product,size*sizeof(Products)); //Double the size while keeping the same elements
}
product[count++]= newProduct;
//cout<<line<<endl; //LINES ARE Printing!
}
}
for (int i = 0; i<count; i++){
// cout<<product[i].getproduct_name()<<endl; //Prints Product name--Works
}
for (int i = 0; i<count; i++){
//cout<<product[i].getproduct_num()<<endl; //Prints Product number--Works
}
}

Read two words into one char array element

I am trying to read in two words from text file into one char array element. I CANNOT USE std::string. I get a seg fault because my loop is looping in a way that goes out of bounds. I cannot copy in the two words. please help me do this!! My loop for card struct works perfectly. I cannot get the "first last" into the people[].name
// deck of cards
// below are initializations
#include
#include
#include
#include
#include
using namespace std;
//globals
const int maxCards = 52;
//Structs
struct card {
char suit[8];
char rank[6];
int cvalue;
char location;
};
struct player {
char name[100];
int total;
card hand[4];
};
//program
int main()
{
//constants
char tempfName[100];
char templName[100];
//create struct array(s)
card deck[52];
card shuffledDeck[52];
player people[4];
//create pointers
card * deckPointer =NULL;
deckPointer = deck;
card * shuffledDeckPointer=NULL;
shuffledDeckPointer = shuffledDeck;
for(int i=0;i<4;i++)
{
strcopy(people[i].name,"first last");
}
//open player names file
ifstream fin2;
string fin2Name;
//get file name from user
cout << "Enter player file name...(Players.txt)" << endl;
getline(cin, fin2Name);
//open file
fin2.open(fin2Name.c_str());
//check if Players.txt opens correctly
if(!fin2.good())
{
cout << "Error with player file!" << endl;
return 0;
}
else
{
int j =0;
fin2 >> people[j].name; //prime file
while(fin2.good())
{
//find the length
int index =0, length=0;
while(tempfName[length] != '\0')
{
length++;
}
//now add space after first name
tempfName[length] = ' ';
length++;
while(templName[index] != '\0')
{
tempfName[length] = templName[index];
length++;
index++;
}
tempfName[length]='\0';
int counter =0;
while(templName[counter] != '\0')
{
people[0].name[counter] = templName[counter];
counter++;
}
}
}
it seems your tempfName is not pointing to a correct object in your while loop in else statement
else
{
int j =0;
fin2 >> people[j].name; //prime file
while(fin2.good())
{
//find the length
int index =0, length=0;
while(tempfName[length] != '\0')
{
length++;
}
You could do some cheating:
char full_name[256]; // Binary quantities are better.
snprintf(full_name, sizeof(full_name),
"%s %s",
first_name, last_name);
You should do more research regarding C-style string functions, like check a good reference book. It should have a chapter about the C-style string functions.
Here are some helpful ones:
strcpy, strcat, strchr, sprintf, strlen