C++, count repeated words in the string and display - c++

I have string say "walk talk, can't won't Won't woN'T talk." I want to count the reapeated words and display.
Note: it is not case sensitive.
I have used delimeter
strtok(string, ",.;:\"!? -_\n\t*()##=+");
and saved it in
char *temp[100];
Now how can I check for repeatation of words? And display as below
3 won't
2 talk
1 can't
1 walk
it should display from highest repeat to lowest. And if the repeatation is same then display alphabetic order.
Sorry for my bad english.

Use a std::string to hold the result of the strtok(). Then create a std::map<string, int> to hold the count of the times the string (the key) has occurred.
You can populate the map with:
std::map<string, int> myMap;
myMap[tokenizedWord]++; //Increase count of word.
You can then cycle through the map content and print out wherever the integer value is greater than 2.
for (std::map<string, int>::iterator iter = myMap.begin(); iter != myMap.end(); ++iter)
{
if (iter->second > 1)
std::cout << "Duplicated word: " << iter->first << " count = " << iter->second;
}
I'll let you figure out how to traverse it in order. You can put the values in a vector or something and use std::sort before printing or whatever else you like. Maps, unfortunately, are associative containers and you can't sort them as it breaks their internal ordering.
Background Info on std::map
A map is an associative array meaning that every key maps to a specific value, and keys are unique. You can actually create a multimap where keys are not unique, so that's why this is important.
Basically, since keys are unique, you can access or create an element just by using the key as the array index.
For example:
//Create a map and insert a couple things into it - prices of meat?
std::map<string, float> myMap;
myMap["Chicken"] = 4.99;
myMap["Turkey"] = 6.99;
//Retrieve the price of something using the key.
std::cout << "Chicken costs " << myMap["Chicken"] << std::end;
You can do standard insertion and location operations on a map too, but the associative array syntax is just simpler, so why bother? :)
PS: To fully answer your comment, just in case, the ++ at the end of myMap[tokenizedWord]++ is just saying to increment the value of the integer value stored for that key by 1. You could just as well do myMap[tokenizedWord] = myMap[tokenizedWord] + 1 OR you could also do myMap[tokenizedWord] += 1.

a complete implementation of your problem (Let me know if you want a sample code for sorting):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define ARRAY_ELEMS_COUNT(A) sizeof(A)/sizeof(*A)
typedef struct _word_t
{
char *word;
int occurr_count;
struct _word_t *next;
} word_t;
typedef struct _word_list_t
{
struct _word_t *head;
struct _word_t *tail;
int elems_count;
} word_list_t;
/* Creation of the words list */
word_list_t *make_list(void)
{
word_list_t *w_list = (word_list_t *)malloc(sizeof (struct _word_list_t));
if (w_list == NULL)
{
fprintf(stderr, "malloc faild --> %s\n", strerror(errno));
return NULL;
}
w_list->head = w_list->tail = NULL;
w_list->elems_count = 0;
return w_list;
}
int list_word_lookup(word_list_t *w_list, char *word)
{
word_t *temp_word = w_list->head;
while(temp_word)
{
if (strcmp(temp_word->word, word) == 0)
{
/* We got it before, increment the count */
temp_word->occurr_count++;
return 1;
}
else
{
temp_word = temp_word->next;
}
}
return 0;
}
/* Adding new words to the list of words if they are not present, otherwise increment their occurrence count */
/* TODO : Sort the list using Merge sort for performance */
int adding_to_list(word_list_t *w_list, char *word)
{
int return_status = 0;
char *tmp_word = (char *)malloc(sizeof(char)*(strlen(word) + 1));
word_t *new_word = (word_t *)malloc(sizeof(struct _word_t));
/* Empty list */
if (w_list->head == NULL)
{
strcpy(tmp_word, word);
new_word->word = tmp_word;
new_word->occurr_count = 1;
w_list->head = w_list->tail = new_word;
w_list->head->next = NULL;
w_list->elems_count++;
}
else
{
/* The list is not empty */
/* Checking if the word exist in the list */
return_status = list_word_lookup(w_list, word);
if (return_status == 1)
{
fprintf(stdout, "WE got this word before --> increment count\n");
}
else
{
strcpy(tmp_word, word);
new_word->word = tmp_word;
new_word->occurr_count = 1;
w_list->tail->next = new_word;
w_list->tail = new_word;
w_list->tail->next = NULL;
}
}
return 0;
}
void words_list_dump(word_list_t *w_list)
{
word_t *temp;
for (temp = w_list->head; temp; temp = temp->next) {
fprintf(stdout, "Word : %s -- Count = %d\n", temp->word, temp->occurr_count);
}
}
/* Destroying all words */
void free_words(word_list_t *w_list)
{
word_t *temp;
for (temp = w_list->head; temp; temp = temp->next) {
/* Freeing the word string */
free(temp->word);
/* Freeing the word */
free(temp);
}
w_list->head = NULL;
w_list->tail = NULL;
}
/* Destroying the words list */
void free_words_list(word_list_t *w_list)
{
if (!w_list)
{
return;
}
free_words(w_list);
free(w_list);
}
/* TODO : create a function that converts your input text to a char ** array, so you can pass it to adding_to_list */
/* For testing */
int main(int argc, char **argv)
{
const char *string[] = {"Hello", "World", "Stackoverflow", "C", "Hello", "C", "WORDS", "words", "List", "list", "Hello", "World", "Count"};
word_list_t *my_list = make_list();
int i;
for (i = 0; i < ARRAY_ELEMS_COUNT(string); i++)
adding_to_list(my_list, string[i]);
words_list_dump(my_list);
free_words_list(my_list);
return 0;
}

Here is an answer using strtok but without std::map. In one pass of string, every word in is checked against previous words and repeats are counted.
#include <iostream>
using std::cin;
using std::cout;
using std::endl;
#include <string>
using std::string;
#include <vector>
using std::vector;
#include <cstring>
using std::tolower;
int main()
{
char *strin;
string inputstr;
vector<string> svec;
vector<int> cvec;
char *pch;
int unique_word_count=0;
while(getline(cin,inputstr))
{
//token-ize the string
//First string
strin = &inputstr[0];
pch = std::strtok(strin," ,-");
bool unique_word_found = true;
//subsequent words
while (pch != NULL)
{
string word(pch);
for(string::size_type i=0; i < word.size(); i++)
word[i]=tolower(word[i]);
//first word
//just add to svec and no comparisons
if(unique_word_count==0)
{
svec.push_back(word);
cvec.push_back(1);
cvec[unique_word_count++]=1; //init count of first word
//next word
pch = std::strtok(NULL, " ,-");
unique_word_found = true; //reset flag
continue;
}
//start comparing with other words currently in string vector
//do not do this if only 1 word present
vector<string>::iterator iter=svec.begin();
while(iter < svec.end())
{
if(word == *iter)
{
//match found
cvec[iter-svec.begin()]++; //increment count of that word
unique_word_found = false;
}
iter++;
}
if(unique_word_found)
{
//add to unique word list and increment count
svec.push_back(word);
cvec.push_back(1);
cvec[unique_word_count++]=1;
}
//next word
pch = std::strtok(NULL, " ,-");
unique_word_found = true; //reset flag
}
}
cout << "Word" << " ---> " << "Occurences" << endl;
for(vector<string>::size_type i=0; i < svec.size(); i++)
{
cout << svec[i] << " ---> " << cvec[i] << endl;
}
return 0;
}

The general strategy can be as follows:
Sanitize the input (convert all characters to lower case, remove unwanted punctuation, etc.)
Walk through the input
Add each character to a string, finalizing when a space is encountered
Add the string to a key-value structure. The string is the key. If this is a new entry not already contained in the structure, set the value 1. Otherwise set it to the current value + 1 (so as to count the number of times encountered so far).
Repeat for each word
Walk through the key-value structure and print each entry.

Related

I'm getting this warning sign Array index 4001 is past the end of the array (which contains 4001 elements)

I have two questions
First: When i try to run the code it gives me a warning where it says "Array index 4001 is past the end of the array (which contains 4001 elements)"
Second: I want to read the words from the file and then pass them through the function so i can
add the words to the hash table and index them accordingly and print the count of the unique words from the text file. the size function does that. can someone please help me with this
#include <iostream>
#include <string>
#include <fstream>
#define HASHSIZE 4001
using namespace std;
class entry {
public:
string word;
int frequency;
entry() { frequency = 0; }
};
class Hashtable {
private:
entry entryArr[HASHSIZE];
int updateArr[HASHSIZE];
int costArr[HASHSIZE];
int sizeUnique = 0;
int probeCount;
int updateCount;
public:
int HashKey(string key)
{
int totalsum = 0;
// this function is to assign every word a key value to be stored against.
for (int i = 0; i < key.length(); i++) totalsum += int(key[i]);
return (totalsum % HASHSIZE);
}
void update(string key) {
int k = HashKey(key);
if (entryArr[k].frequency == 0) {
entryArr[k].frequency++;
updateCount++;
probeCount++;
sizeUnique++;
}
// function to enter the unique words in the array
else if (entryArr[k].word == key) {
entryArr[k].frequency++;
probeCount++;
}
while (entryArr[k].frequency != 0 && entryArr[k].word != key) {
k++;
}
if (entryArr[k].word == key) {
entryArr[k].frequency++;
} else {
entryArr[k].word = key;
}
sizeUnique++;
updateCount++;
probeCount++;
}
int probes() {
costArr[HASHSIZE] = probeCount;
return probeCount;
}
int size() // function to count the total number of unique words occuring
{
int count = 0;
updateArr[HASHSIZE] = updateCount;
for (int i = 0; i < HASHSIZE; i++)
if (updateArr[HASHSIZE] != 0) {
count = costArr[i] / updateArr[i];
}
cout << count;
return count;
}
};
int main() {
entry e;
Hashtable h;
ifstream thisfile("RomeoAndJuliet.txt");
if (thisfile.is_open()) {
while (!thisfile.eof) {
h.update(e.word);
}
thisfile.close();
cout << "The total number of unique words are: " << h.size();
}
return 0;
}
An array with 4001 elements has valid indexes 0,1,...,3999,4000 as C++ is indexing from 0.
When i try to run the code it gives me a warning where it says "Array index 4001 is past the end of the array (which contains 4001 elements)"
This is because array index starts with 0 instead of 1. And so an array of size 4001 can be safely indexed(accessed) upto 4000 and not 4001.
I want to read the words from the file and then pass them through the function so i can add the words to the hash table and index them accordingly and print the count of the unique words from the text file
The below program shows how to do this. The program shown below counts how many times a given word occurred in a given input.txt file and then print that count infront of the word.
#include <iostream>
#include <map>
#include <sstream>
#include<fstream>
int main() {
std::string line, word;
//this map maps the std::string to their respective count
std::map<std::string, int> wordCount;
std::ifstream inFile("input.txt");
if(inFile)
{
while(getline(inFile, line, '\n'))
{
std::istringstream ss(line);
while(ss >> word)
{
//std::cout<<"word:"<<word<<std::endl;
wordCount[word]++;
}
}
}
else
{
std::cout<<"file cannot be opened"<<std::endl;
}
inFile.close();
std::cout<<"Total unique words are: "<<wordCount.size()<<std::endl;
for(std::pair<std::string, int> pairElement: wordCount)
{
std::cout << pairElement.first <<"-" << pairElement.second<<std::endl;
}
return 0;
}
The output of this program can be seen here.
Note that(as shown in above example) there is no need to create a separate class for the purpose given in your second question. We can do this(as shown above) literally using 4 to 6 lines(excluding opening and closing the file) of code.

Split a sentence like 1100010011 into words in C++

I am parsing a string "1100010011" in C++ using the following:
string instring = "1100010011";
char last = instring.at(0);
string res = "";
vector<string> _chain;
int len_end = instring.length();
int len_instring = len_end + 1;
for (int count = 0; count != len_instring; ++count){
if (count != len_end && instring.at(count) == last) {
res += last;
}
else
{
_chain.push_back(res);
if (count != len_end) {
last = instring.at(count);
res = last;
};
};
};
The result is '1100010011' -> '11', '000', '1', '00', '11'.
But I think this code are pretty dumb.
Is there a way to improve this code?
upd (10 feb 2021):
Is there a way to use bitwise logical operations to rewrite this code for faster splitting? If you imagine a text string with bits as a regular digit. 1100010011 = 313
its a simple iteration.. take a value 'x' as the current index character and increment the pointer until the value while pointer is not equal to the x, the pointer will stop when it will get value not equal to x,now update the x...
string s;
cin>>s;
int sz=s.size();
for(int i=0;i<sz;)
{
char x=s[i];
while(s[i]==x)
{
cout<<s[i];
i++;
}
cout<<" ";
}
std::string has a find_first_not_of member function that you can use to find the first letter that is different to the current character.
So you can do a loop like this:
#include <iostream>
#include <vector>
int main()
{
auto input = std::string("1100010011");
std::vector<std::string> vec;
size_t it = 0;
size_t last = 0;
while ((it = input.find_first_not_of(input[it], last)) != std::string::npos)
{
vec.push_back(input.substr(last, it-last));
last = it;
}
vec.push_back(input.substr(last, input.size() - last));
}
Here is my proposition.You can find the explanations in the comments:
#include <iostream>
#include <vector>
using namespace std;
int main()
{
string s = "1100010011";
//string s = "1100010011222333";
vector<string> chain;
// the first char of the string
std::string temp ;
char tmp = s[0];
// run though the characters of the string
for (char x : s)
{
// compare each character
if ( x != tmp )
{
//cout << x << endl;
tmp = x;
// if different then add the constructed string from temp and clear temp to receive new sets of characters
chain.push_back(temp);
temp.clear() ;
}
// we add the character to temp anyway
temp.push_back(x);
}
// we add the last constructed value from temp
chain.push_back(temp);
for (string x : chain)
{
std::cout << x << " " ;
}
}
test cases :
Input 1100010011 provides the ouput:
11 000 1 00 11
Input 1100010011222333 provides the ouput:
11 000 1 00 11 222 333

How can I read and output the contents of.txt file using C++?

I have been assigned as a school project to check the the frequency of occurrence of 26 lowercase letters, and then they are encoded by Hoffman code. In this assignment, the basic requirement is (1)to read the given text file and open it on the terminal and (2)to output the number of occurrence of lowercase letters and their corresponding encoded Hoffman code.
I was able to accomplish the (2) task but whenever I am trying to output the text on the terminal, my code was not able to count the occurrence of the lowercase letters and output their respective Huffman code.
terminal showing only the text content
output without the inclusion of code for reading the text on terminal
Here is my code for the assignment:
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <bits/stdc++.h>
int ch;
FILE *file;
using namespace std;
struct Node
{
// data members of each node of Huffman tree - alphabet and its frequency
char data;
unsigned freq;
// pointers to left and right childs
Node *left, *right;
// constructor to initialize the data members of the Huffman tree node
Node(char d, unsigned f)
{
data = d;
freq = f;
left = NULL;
right = NULL;
}
};
struct compare
{
// overloading () to compare which of left,right childs have higher frequency
bool operator()(Node* l, Node* r)
{
return (l->freq > r->freq);
}
};
// recursive function to display huffman codes
void display(struct Node* root, string str)
{
// if tree is empty return
if (!root)
return;
if (root->data != '$')
cout << root->data << ": " << str << "\n";
// recursively call left, right childs
display(root->left, str + "0");
display(root->right, str + "1");
}
// build huffman tree
void createHuffmanTree(char data[], int freq[], int size)
{
struct Node *left, *right, *top;
// Create a min heap using STL
priority_queue<Node*, vector<Node*>, compare> minHeap;
// push alphabets, frequency into minheap as leaf nodes
for (int i = 0; i < size; ++i)
minHeap.push(new Node(data[i], freq[i]));
// repeat until heap size becomes one
while (minHeap.size() != 1)
{
// Extract two least frequent items from minheap
left = minHeap.top();
minHeap.pop();
right = minHeap.top();
minHeap.pop();
// Create new internal node with two least frequent items as child nodes
// frequency of internal node is equal to sum of frequency of child nodes
top = new Node('$', left->freq + right->freq);
top->left = left;
top->right = right;
// push newly created internal node into minheap
minHeap.push(top);
}
// building Huffman tree is done
// display Huffman codes for alphabets
cout << "The Huffman codes for lower case characters: " << endl;
display(minHeap.top(), "");
}
// reading text file
void readTxt() {
FILE * txt;
char ch;
if (txt != NULL)
{
// open file to read english article
txt = fopen("D:\\data3.txt", "r");
do
{
ch = fgetc(txt);
putchar(ch);
} while(ch != EOF);
//fclose(txt);
} else {
cout << "There is no such .txt file in the system." << endl;
exit(0);
}
}
int main()
{
int charCount = 0;
int freq[26] = {0};
readTxt();
// reads english article from file and counts frequency of each lowercase alphabet
while (1)
{
ch = fgetc(file);
if (ch == EOF)
break;
if (ch >= 'a' && ch <= 'z')
{
freq[ch - 'a']++;
// count total number of lowercase alphabets in file
charCount++;
}
}
fclose(file);
// display total number of characters in file
cout << "Number of lowercase alphabets in file: " << charCount << endl;
char arr[] = { 'a','b','c','d','e','f',
'g','h','i','j','k','l',
'm','n','o','p','q','r',
's','t','u','v','w','x',
'y','z' };
// display frequency of lowercase characters
cout << "Frequency of lowercase characters: " << endl;
int freqCount = 0;
for(int i = 0; i < 26; i++)
{
if(freq[i]!=0)
{
cout << arr[i] << " : " << freq[i] << endl;
// count number of lowercase alphabets with frequency greater than zero
freqCount++;
}
}
char arr1[freqCount];
int k = 0, freq1[freqCount];
// copy lowercase alphabets with frequency greater than zero into arr1, freq1
for(int i = 0; i < 26; i++)
{
if(freq[i]!=0)
{
arr1[k] = arr[i];
freq1[k++] = freq[i];
}
}
// call method to create Huffman tree
createHuffmanTree(arr1, freq1, freqCount);
return 1;
}
It will be a great help if you guide me through my mistake.
TIA

How to "Fold a word" from a string. EX. "STACK" becomes "SKTCA". C++

I'm trying to figure out how to can fold a word from a string. For example "code" after the folding would become "ceod". Basically start from the first character and then get the last one, then the second character. I know the first step is to start from a loop, but I have no idea how to get the last character after that. Any help would be great. Heres my code.
#include <iostream>
using namespace std;
int main () {
string fold;
cout << "Enter a word: ";
cin >> fold;
string temp;
string backwards;
string wrap;
for (unsigned int i = 0; i < fold.length(); i++){
temp = temp + fold[i];
}
backwards= string(temp.rbegin(),temp.rend());
for(unsigned int i = 0; i < temp.length(); i++) {
wrap = fold.replace(backwards[i]);
}
cout << wrap;
}
Thanks
#Supreme, there are number of ways to do your task and I'm going to post one of them. But as #John had pointed you must try your own to get it done because real programming is all about practicing a lot. Use this solution just as a reference of one possibility and find many others.
int main()
{
string in;
cout <<"enter: "; cin >> in;
string fold;
for (int i=0, j=in.length()-1; i<in.length()/2; i++, j--)
{
fold += in[i];
fold += in[j];
}
if( in.length()%2 != 0) // if string lenght is odd, pick the middle
fold += in[in.length()/2];
cout << endl << fold ;
return 0;
}
good luck !
There are two approaches to this form of problem, a mathematically exact method would be to create a generator function which returns the number in the correct order.
An easier plan would be to modify the string to solve practically the problem.
Mathematical solution
We want a function which returns the index in the string to add. We have 2 sequences - increasing and decreasing and they are interleaved.
sequence 1 :
0, 1 , 2, 3.
sequence 2
len-1, len-2, len-3, len-4.
Given they are interleaved, we want even values to be from sequence 1 and odd values from sequence 2.
So our solution would be to for a given new index, choose which sequence to use, and then return the next value from that sequence.
int generator( int idx, int len )
{
ASSERT( idx < len );
if( idx %2 == 0 ) { // even - first sequence
return idx/2;
} else {
return (len- (1 + idx/2);
}
}
This can then be called from a function fold...
std::string fold(const char * src)
{
std::string result;
std::string source(src);
for (size_t i = 0; i < source.length(); i++) {
result += source.at(generator(i, source.length()));
}
return result;
}
Pratical solution
Although less efficient, this can be easier to think about. We are taking either the first or the last character of a string. This we will do using string manipulation to get the right result.
std::string fold2(const char * src)
{
std::string source = src;
enum whereToTake { fromStart, fromEnd };
std::string result;
enum whereToTake next = fromStart;
while (source.length() > 0) {
if (next == fromStart) {
result += source.at(0);
source = source.substr(1);
next = fromEnd;
}
else {
result += source.at(source.length() - 1); // last char
source = source.substr(0, source.length() - 1); // eat last char
next = fromStart;
}
}
return result;
}
You can take advantage of the concept of reverse iterators to write a generic algorithm based on the solution presented in Usman Riaz answer.
Compose your string picking chars from both the ends of the original string. When you reach the center, add the char in the middle if the number of chars is odd.
Here is a possible implementation:
#include <iostream>
#include <string>
#include <vector>
#include <utility>
#include <algorithm>
#include <iterator>
template <class ForwardIt, class OutputIt>
OutputIt fold(ForwardIt source, ForwardIt end, OutputIt output)
{
auto reverse_source = std::reverse_iterator<ForwardIt>(end);
auto reverse_source_end = std::reverse_iterator<ForwardIt>(source);
auto source_end = std::next(source, std::distance(source, end) / 2);
while ( source != source_end )
{
*output++ = *source++;
*output++ = *reverse_source++;
}
if ( source != reverse_source.base() )
{
*output++ = *source;
}
return output;
}
int main() {
std::vector<std::pair<std::string, std::string>> tests {
{"", ""}, {"a", "a"}, {"stack", "sktca"}, {"steack", "sktcea"}
};
for ( auto const &test : tests )
{
std::string result;
fold(
std::begin(test.first), std::end(test.first),
std::back_inserter(result)
);
std::cout << (result == test.second ? " OK " : "FAILED: ")
<< '\"' << test.first << "\" --> \"" << result << "\"\n";
}
}

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