Using fstream to write a string in a file is putting a blank space between every letter, the string i am writing comes from a function that converts binary code into a ascii:
void almacenar(string texto)
{
string temp;
string test = "hola";
string compreso ="";
remove("compreso.daar");
int textosize=texto.size();
int i = 0;
while (i<textosize){
while(temp.size()!=8){
temp=temp+texto[i];
i++;
if (i>=textosize) {
break;
}
}
compreso=compreso+bitoascii(temp);
temp.clear();
}
Escribir(test,"compreso.daar");
}
int Escribir(string i,const char* archivo)
{
fstream outputFile;
outputFile.open(archivo, fstream::app);
outputFile<<i;
outputFile.close();
return 0;
}
string bitoascii(std::string data)
{
std::stringstream sstream(data);
std::string output;
while(sstream.good())
{
std::bitset<8> bits;
sstream >> bits;
char c = char(bits.to_ulong());
output += c;
}
return output;
}
The file sould have "Ø" have "Ø " or "ØØ" is "Ø Ø" if i print via console the string that contains Ø it has no spaces
In the function bitoascii(), after transferring data from sstream to bits you are not checking if the transfer succeeded and instead of having converted data, the value of bits is 0x00 and the value is recorded in the file, but the character '\0' is not printable.
Just add a sstream.good() to know if bits has been correctly
written before adding the characters in the output string.
The function bitascii() should be:
string bitoascii(std::string data)
{
std::stringstream sstream(data);
std::string output;
while(sstream.good())
{
std::bitset<8> bits;
sstream >> bits;
// check is the transfer failed then exit from while
if (!sstream.good()) break;
char c = char(bits.to_ulong());
output += c;
}
return output;
}
Related
I am currently working on a project to read binary data from a file do stuff with it and to write it back again. The reading works well so far, but when I try to write the binary-data stored in a string to a file, it writes the binarys as text. I think it has soemthing to do with the opening mode.
Here is my code:
void WriteBinary(const string& path, const string& binary)
{
ofstream file;
file.open(path);
std::string copy = binary;
while (copy.size() >= 8)
{
//Write byte to file
file.write(binary.substr(0, 8).c_str(), 8);
copy.replace(0, 8, "");
}
file.close();
}
In the function above the binary parameter looks like this: 0100100001100101011011000110110001101111
With the help of "aschelper" I was able to create a solution for this problem. I converted the binary string to its usual representation, before writing it to the file. My code is below:
// binary is a string of 0s and 1s. it will be converted to a usual string before writing it into the file.
void WriteBinary(const string& path, const string& binary)
{
ofstream file;
file.open(path);
string copy = binary;
while (copy.size() >= 8)
{
char realChar = ByteToChar(copy.substr(0, 8).c_str());
file.write(&realChar, 1);
copy.replace(0, 8, "");
}
file.close();
}
// Convert a binary string to a usual string
string BinaryToString(const string& binary)
{
stringstream sstream(binary);
string output;
while (sstream.good())
{
bitset<8> bits;
sstream >> bits;
char c = char(bits.to_ulong());
output += c;
}
return output;
}
// convert a byte to a character
char ByteToChar(const char* str) {
char parsed = 0;
for (int i = 0; i < 8; i++) {
if (str[i] == '1') {
parsed |= 1 << (7 - i);
}
}
return parsed;
}
I need a program to take a string and replace spaces with increasing numbers.
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// Get the String
string str = "this essay needs each word to be numbered";
int num = 1;
string x = num;
int i = 0;
// read string character by character.
for (i < str.length(); ++i) {
// Changing the loaded character
// to a number if it's a space.
if (str[i] == ' ') {
str[i] = x;
++num
}
}
// testing outputs
cout << str << endl;
cout << num << endl;
ofstream file;
file.open ("numbered.txt");
file << str;
file.close();
return 0;
}
I had it at the point where it could replace spaces with a letter or symbol and save to a new file but when I tried to make it a number it stopped working. I would need it to say "this1essay2needs3each4word5to6be7numbered
For ease and clarity, change your approach.
Put the string into an istringstream
Extract each space-separated substring and place into an std::vector<string>
Feed the contents of the vector into a stringstream and
use std::to_string(num) to add the numbers between the substrings
e.g.:
std::string str = "this essay needs each word to be numbered";
int num = 1;
std::istringstream istr(str);
std::string temp;
std::vector<std::string> substrs;
while (istr >> temp)
{
substrs.push_back(temp);
}
std::stringstream ostr;
for (auto&& substr : substrs)
{
ostr << substr << std::to_string(num++);
}
Let's break the problem down into parts. We can make a SpaceReplacer object that does the replacement. It has an Output, which it can use as a function to output characters:
template<class Output>
struct SpaceReplacer {
Output output;
int num_spaces;
void input(char c) {
if(c == ' ') {
auto num_as_string = std::to_string(num_spaces);
num_spaces += 1;
for(char digit : num_as_string) {
output(digit);
}
}
else {
output(c);
}
}
};
Every time you input a character, it either outputs the character you input, or it outputs the digits of the number (if the character was a space).
We should write a helper function to make SpaceReplacers:
template<class Output>
SpaceReplacer<Output> makeReplacer(Output output_func) {
return SpaceReplacer<Output>{output_func, 0};
}
Reading one string, returning new string
It's now easy to write a function that replaces spaces in a string.
std::string replaceSpaces(std::string const& input) {
std::string output_string;
// We output chars by appending them to the output string
auto output_func = [&](char c) { output_string += c; };
auto replacer = makeReplacer(output_func);
for(char c : input) {
replacer.input(c);
}
return output_string;
}
Reading input from file, replacing spaces and returning a string
Because we wrote a really generic SpaceReplacer class, we can modify the function so that it'll read input directly from a FILE*
std::string replaceSpaces(FILE* file) {
std::string output_string;
auto output_func = [&](char c) { output_string += c; };
auto replacer = makeReplacer(output_func);
while(true) {
int input_char = fgetc(file);
if(input_char == EOF) {
break;
}
replacer.input(input_char);
}
return output_string;
}
Reading input from one file, immediately appending it to different file with spaces replaced
We can also read directly from one file, and output directly to another file, with no delay. This might be useful if you were processing a very large amount of data.
void replaceSpaces(FILE* input_file, FILE* output_file) {
auto output_func = [=](char c) { fputc(c, output_file); };
auto replacer = makeReplacer(output_func);
while(true) {
int input_char = fgetc(input_file);
if(input_char == EOF) {
break;
}
replacer.input(input_char);
}
}
In this case, you need to use another string for the result.
#include <cstring>
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
int main()
{
// Get the String
string result, str = "this essay needs each word to be numbered qwe qwe wqe qwe qwe qwe q";
int num = 0;
int i;
// read string character by character.
for (i=0; i < str.length(); i++) {
// Changing the loaded character
// to a number if it's a space.
if (str[i] == ' ')
result+=std::to_string(++num);
else
result+=str[i];
}
// testing outputs
cout<<result<<endl;
cout<<num;
ofstream file;
file.open ("numbered.txt");
file << result;
file.close();
return 0;
}
You have to replace it with a character, not by a number.
str[i] = num+'0';
this code will only read and calculate the first input in the input.txt file and ignore the rest of the inputs in the input file.I have been trying to solve it so that it can read all the rest of the inputs and calculate them.
this is my code i think there is something wrong with it.
i have tried several looping methods
int main()
{
string inputLine;
ifstream file ("input.txt");// input file to be read
ofstream file1;
file1.open("output.txt");
freopen("output.txt", "w", stdout);// store all the output to this file
while (std::getline (file, inputLine)) // read the strings in the input file
{
if( strncmp( "----", inputLine.c_str(), 4 ) == 0 )
continue;
//calculating binary and hexadecimal values
char *opr = "^+-/%*=,()";
std::string::iterator end_pos = std::remove(inputLine.begin(),
inputLine.end(), ' ');
inputLine.erase(end_pos, inputLine.end());
string str=inputLine;
string str2="";
int length=str.length();
char t[length];
str.copy(t, length);
t[length] = '\0';
char* tok;
char *cop=new char [length];
str.copy(cop,length);
char *w = strtok_fixed( t, opr );
while (w!=NULL)
{
string w2=w;
std::stringstream tr;
tr << w2;
w2.clear();
tr >> w2;
int x=w2.length();
int y=x-3;
string check= w2.substr(0,3);
string check1=w2.substr(0,x);
if(check.find("0x") != std::string::npos)
{
unsigned int x= strtol(w2.c_str(), NULL, 0);
std::ostringstream s;
s << x;
const std::string ii(s.str());
str2=str2+ ii;
}
else if (check1.find("b")!=std::string::npos)
{
w2.pop_back();
long bin=std::strtol(w2.c_str(),0,2);
std::ostringstream s2;
s2<<bin;
const std::string t2(s2.str());
//inputLine.replace(inputLine.find(w2),(w2.length()+1),t2);
str2=str2+t2;
}
else
{
str2=str2+w2;
}
char a =cop[w-t+strlen(w)];
string s1="";
s1=s1+a;
std::stringstream tr1;
tr1 << s1;
s1.clear();
tr1 >> s1;
str2=str2+s1;
w = strtok_fixed (NULL, opr);
}
//str2 should be taken to the parser for final evaluations
Parser p(str2);
double value = p.Evaluate ();
std::cout<<"----------------------"<<endl;
std::cout << "Result = " << value << std::endl;
std::cout<<"----------------------"<<endl;
return 0;
}
}
The problem is at the end
return 0;
}
}
should be
}
return 0;
}
You are returning from inside your while loop instead of after your while loop finishes.
You should spend the time to indent your code correctly. It will help you spot this kind of error. You should also learn to break up your code into smaller functions. Again this will help you understand your own code a bit better.
I am trying to match words from user input with a string from a text file.
When this code runs, it crashes after the file is opened. (marked by ****)
How can I change it to properly match the strings from user input with strings from the text file.
Any help would be appreciated, thank you.
const int Size = 81; // 80 characters for the line + 1 for the '\0'
const int MaxNumberOfWords = 10;
int main() {
char input[81], temp[81], fin[81];
printf("Input a string\n");
fgets(input, 81, stdin);
int len = strlen(input);
char *div;
div = strtok(input, " ");
while (div != NULL) {
printf("%s\n",div);
div = strtok(NULL, " ");
ifstream inStream; // declare an input stream for my use
char theWords[ MaxNumberOfWords][ Size]; // Array to store words from input line
int wordRow = 0; // Row for the current word
char wordToLookup[ Size]; // word to lookup
bool wordWasFound = false; // flag to track whether or not word is found
char c; // stores return character after input
inStream.open( "C:\\Users\\dqiao4\\Desktop\\Dev-Cpp\\dictionaryMax6.txt");
assert( ! inStream.fail() ); // make sure file open was OK
//*****this is where the code crashes
while ( inStream >> theWords[ wordRow]) {
wordRow++;
}
for (int i=0; i<wordRow; i++) {
// See if this word matches
if ( strcmp( div, theWords[ i]) == 0 ){
wordWasFound = true;
break; // quit looking
}
}
}
}
int main() {
char input[81];int i=0,j=0,k=0;
cout<<"Input a string ";
while(i<=80){
input[i]=getch();
cout<<input[i];
if(input[i]=='.')
break;
i++;
}
ifstream File("C:\\User\\New.txt");
string line;
if(File)
{
while(getline(File, line))
{
char buff[1024];
strcpy(buff, line.c_str());
while(j<35){
k=0;
while(k<i){
if(buff[j]==input[k])
{
int j1=j,k1=k;
while(true){
if(buff[j1]==input[k1])
{
if(input[j1]=='.'){
cout<<"match";
return 0;
}
j1++;k1++;
}
else
break;
}
}k++;
}j++;
cout<<endl;
}
}
}
}
#inlude <sstream>
#include <string>
in your source and read the text file in string stream buffer, convert it to string and do
auto pos = file_in_str.find("word_to_find");
That pos is the the starting index of word in file
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