#include <iostream> // std::cout
#include <cstdlib>
#include <climits>
#include <algorithm>
#include <cmath>
#include <fstream>
using namespace std;
struct student{
int ID; // ID
string firstname; // first name
string lastname; // last name
int date; // YYMMDD
static bool sort_date(student a, student b){
long data1;
long data2;
data1 = a.date;
data2 = b.date;
if(data1 < 150000){
data1 += 20000000;
}
else{
data2 += 19000000;
}
if(data2 < 150000){
data2 += 20000000;
}
else{
data1 += 19000000;
}
return data1 < data2;
}
};
bool is_num(const string &s);
void input_year(student &students);
int length_of_int(int x);
int main(){
student students[5];
students[0].date = 000101;
students[1].date = 951230;
students[2].date = 570509;
students[3].date = 120915;
students[4].date = 020324;
stable_sort(students, students + 5, student::sort_date);
ofstream file;
file.open("sort_date.txt");
for(int i = 0; i < 5; i++){
file << students[i].date << endl;
}
return 0;
}
void input_year(student &students){
while(true){
string input;
cin >> input;
if(is_num(input)){
students.date = atoi(input.c_str());
if(length_of_int(students.date) != 6){
cout << "Error, try again." << endl;
}
else{
//
break;
}
}
else{
cout << "Error, try again." << endl;
}
}
}
bool is_num(const string &s){
string::const_iterator it = s.begin();
while(it != s.end() && isdigit(*it)){
++it;
}
return !s.empty() && it == s.end();
}
int length_of_int(int input){
int length = 0;
while(input > 0){
length++;
input /= 10;
}
return length;
}
This is my code above and I'm not sure what else to do to sort the dates.. I've been working on this for a while and can't get it right. I need help, preferably a code which solves my problem.
Basically, the type of date is "YYMMDD", so in sort_date function, I make those integers in format of "YYYYMMDD" and then sort them and then again become YYMMDD. However, the sorting is somehow wrong.. I tried several times, and when writing a date like "010101" in the file, it removes the first "0", so I am looking for help with those two problems. Any help is appreciated.
If a leading 0 is significant, then you don't have an int, but a string. You can check whether strings are sorted using < just as well as you can ints.
Also look at your if-else for adding 19 or 20; you check data1 but then modify data2 (and vice versa)....
Starting a number with 0 in C means that the base should be interpreted as octal (base 8 rather than 10): the literal 020324 will be interpreted as the decimal number 8404.
First convert dates to time_t or tm, then use datetime library (http://en.wikipedia.org/wiki/C_date_and_time_functions)
Related
I have to write a programs that takes an input of string which has some '$' and digits. The output of the program is set of all possible strings where the '$ in the string is replaced by all the other digits.
I have written the following code for it.
#include<bits/stdc++.h>
using namespace std;
int numberOf(string in)
{
int count = 0;
for(int i = 0; i <= in.size()-1; i++)
if(in[i] == '$')
count++;
return count;
}
void solve(string in, string in1, vector <string> &s,
int index)
{
if(numberOf(in) == 0)
{
s.push_back(in);
return;
}
if(index == in.size())
{
return;
}
if(in1.empty())
{
return;
}
else
{
if(in[index] == '$')
{
string in2 = in;
in2[index] = in1[0];
string in3 = in1;
in3.erase(in3.begin());
solve(in2, in1, s, index+1);
solve(in, in3, s, index);
return;
}
else
{
solve(in, in1, s, index+1);
return;
}
}
}
void replaceDollar(string in)
{
string in1 = in;
int count = 0;
for(int i = 0; i <= in.size()- 1; i++)
{
if(in[i] != '$')
{
in1.push_back(in[i]);
count++;
}
}
count = in.size() - count;
cout << "Number is " << count << "\n";
vector <string> s;
solve(in, in1, s, 0);
for(auto i = s.begin(); i != s.end(); i++)
cout << *i << " ";
cout << "\n";
}
int main()
{
int t;
cin >> t;
while(t--)
{
string in;
cin >> in;
replaceDollar(in);
}
return 0;
}
For following input
1
$45
The expected output should be
445 545
But it returns
445 545 445 545
Can anyone please explain why is it outputting repeated strings?
Also can anyone suggest a better approach to this question?
Thanks in advance!
Assuming that this is homework:
Start over. Your code is way too complex for this problem.
I would treat everything as type char
Loop/iterate over said string, using std::string::replace() to replace each instance of $ with each digit.
-- If your teacher doesn't want you using std libraries, then add another loop and compare yourself.
3a. Of course, add a check, so that you don't replace $ with $
Create a new copy of the string on each iteration.
Print each to stdout as you create them.
See this post:
How to replace all occurrences of a character in string?
p.s. Pro tip: don't use using namespace. Use the full namespace in your calls; e.g.:
Bad
using namespace std;
string = "hello world";
Good
std::string = "hello world";
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.
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
I'm trying to do parsing to some input string reactions read from file at formula :2W+B=8A+10Z, I'm not interested in characters i need only to split and extract the integer values to put them in a vector i.e vector associated with the reaction here is :[2 1 8 10]
i thought about many things: std::strtok(),isdigital(),find_first_of() but they all didn't work for integer values ... can any body help ??
here my try:
int main()
{
std::string input;
std::getline(std::cin, input);
std::stringstream stream(input);
while(1) {
int n;
stream >> n;
char * pch;
pch = strtok (input," ");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.");
}
}
}
This will do what you want in this particular case. However, i suggest that you look into regex to parse your equation better. You may want to consider all possible cases for your input. This includes \,-,* and other operators that you may want to add in your equation. Also, I'm assuming variables in your equation has only one character.
int main()
{
string input;
getline(std::cin, input);
stringstream stream(input);
char tmp[256];
const char *in = input.c_str();
char str[256];
strcpy(str,in);
int x;
tmp[0]='\0';
char c;
vector<int> vec;
//Scan for the digit
//if it is, store the rest of the string back to str
//if it isn't, store the part of the string before a digit to tmp
while (sscanf(str,"%d%s",&x,str) || sscanf(str,"%[^0123456789]%s",tmp,str) > 1)
{
//check if tmp has the form [variable name]+[a string]
//a string can include another variable name and an operator, = in this case
while(sscanf(tmp,"%c+%[^0123456789]",&c,tmp) > 1)
vec.push_back(1);
if (tmp[0]=='\0')
vec.push_back(x);
tmp[0]='\0';
}
//just in case there're more special cases
while(sscanf(str,"%c+%[^0123456789]",&c,str) > 1)
vec.push_back(1);
for(int i = 0; i < vec.size(); i++)
cout << vec[i] << endl;
}
Output:
2
1
8
10
See comments for explanation.
EDIT
Be careful when you have a special case 2W+B=8A+10Z+C+D. Notice the last C D should both have coefficients 1. This could happen in the middle of the equation too.
Here is another solution:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
int main()
{
string equ;
vector<int> digits;
cout << "enter your equation: \n";
cin >> equ;
for (auto i : equ)
{
if (isdigit(i))
{
digits.push_back(stoi(string{i}));
}
}
for (auto& i : digits)
{
cout << i << endl;
}
system("pause");
return 0;
}
You could simply do something like this, for comments see code
#include <iostream>
#include <string>
#include <vector>
std::vector<int> Split(std::string str)
{
std::vector<int> result; // will contain the different ints
// set pointer to first character in the string
char const* pch = str.c_str();
std::string digit; // buffer to keep digits if more than one
int sign = 1; // each number has a sign -1 or 1
for (; *pch; ++pch)
{
if (std::isdigit(*pch)) // if a digit, put in temp buffer
{
digit += *pch;
}
else if (std::isalpha(*pch)) // if not a digit evaluate the ones we have
{
if (digit.empty()) // none so assume 1 before letter e.g. W+2B
{
result.push_back(1*sign);
}
else
{
result.push_back(stoi(digit)*sign);
digit = "";
}
}
else // determine sign of number
{
digit = "";
if (*pch == '+')
{
sign = 1;
}
else if (*pch == '-')
{
sign = -1;
}
}
}
return result;
}
int main()
{
using namespace std;
string expr{"-2W+B=-8A+10Z"};
auto digits = Split(expr);
for (auto& digit : digits)
{
cout << digit << endl;
}
return 0;
}
Phase 1
example 1: I have string text = "01100001" then I want write to file "a"
example 2: I have string text = "0110000101100010" So I want write to file "ab"
NOTE:I solved phase 1 and result of writing is true.
Phase 2
for example 1:
I want read the file and put it to temp.
So temp = "a" and i convert it to "01100001"
for example 2:
I want read the file and put it to temp.
So temp = "ab" and i convert it to "0110000101100010"
Question
in my code i have below input
string text ="00000110101011100010001011111110011011110101100101110101101111010111111110101011"
"00111011000011100011100000100010111110111110111001100001110001110000101001111010"
"00000101";
I did "phase 1" and I opened the file in a hex editor the writing is true.
But after doing "phase 2" temp != text. Why?
My code
#include <iostream>
#include <sstream>
#include <vector>
#include <fstream>
#include <string>
#include <stdlib.h>
using namespace std;
class bitChar{
public:
unsigned char* c;
int shift_count;
string BITS;
bitChar()
{
shift_count = 0;
c = (unsigned char*)calloc(1, sizeof(char));
}
string readByBits(ifstream& inf)
{
string s ="";
while (inf)
{
string strInput;
getline(inf, strInput );
for (int i =0 ; i < strInput.size() ; i++)
{
s += getBits(strInput[i]);
}
}
return s;
}
void setBITS(string X)
{
BITS = X;
}
int insertBits(ofstream& outf)
{
int total = 0 ;
while(BITS.length())
{
if(BITS[0] == '1')
*c |= 1;
*c <<= 1;
++shift_count;
++total;
BITS.erase(0, 1);
if(shift_count == 7 )
{
if(BITS.size()>0)
{
if(BITS[0] == '1')
*c |= 1;
++total;
BITS.erase(0, 1);
}
writeBits(outf);
shift_count = 0;
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
}
if(shift_count > 0)
{
*c <<= (7 - shift_count);
writeBits(outf);
free(c);
c = (unsigned char*)calloc(1, sizeof(char));
}
outf.close();
return total;
}
string getBits(unsigned char X)
{
stringstream itoa;
for(unsigned s = 7; s > 0 ; s--)
{
itoa << ((X >> s) & 1);
}
itoa << (X&1) ;
return itoa.str();
}
void writeBits(ofstream& outf)
{
outf << *c;
}
~bitChar()
{
if(c)
free(c);
}
};
int main()
{
ofstream outf("ssSample.dat",ios::binary);
string text ="00000110101011100010001011111110011011110101100101110101101111010111111110101011"
"00111011000011100011100000100010111110111110111001100001110001110000101001111010"
"00000101";
cout<< text<<endl;
//write to file
bitChar bchar;
bchar.setBITS(text);
bchar.insertBits(outf);
outf.close();
ifstream inf("ssSample.dat" ,ios::binary);
//READ FROM FILE
string temp=bchar.readByBits(inf);
cout << endl;
cout << temp << endl;
return 0;
}
You have a LF Line Feed character. This is the character that is getting omitted.
0000 1010
This may be unrelated, but Windows requires a CR and LF for a new line. This code may act differently in Windows vs. Unix.
Read one byte at a time.
string readByBits(ifstream& inf)
{
string s ="";
char buffer[1];
while (inf.read (buffer, 1))
{
// string strInput;
//getline(inf, strInput );
//for (int i =0 ; i < strInput.size() ; i++)
//{
s += getBits(*buffer);
//}
}
return s;
}
Program output:
000001101010111000100010111111100110111101011001011101011011110101111111101010110011101100001110001110000010001011111011111011100110000111000111000010100111101000000101
000001101010111000100010111111100110111101011001011101011011110101111111101010110011101100001110001110000010001011111011111011100110000111000111000010100111101000000101
One problem with your approach is that your text must be a multiple of 8 bits to work. Otherwise, even if everything is correct, that last character will be read from the file and converted to 8 binary digits in the string adding trailing zeros.
Two problems I quickly identified (but I assume there are more)
Your input is not a multiple of 8-bits
By using getLine you're reading until you meet a delimiting character and thus spoiling your result since you're not dealing with a text-based file