I am currently trying to read a file, put extra backward slash () if it finds a backward slash, and write it to another file. The problem is, there are weird characters being printed inside the path.txt. I suspect that, the space characters from the file logdata is the root of this problem. Need advice how to solve this.
Here is the code:
// read a file
char str[256];
fstream file_op("C:\\logdata",ios::in);
file_op >> str;
file_op.close();
// finds the slash, and add additional slash
char newPath[MAX_PATH];
int newCount = 0;
for(int i=0; i < strlen(str); i++)
{
if(str[i] == '\\')
{
newPath[newCount++] = str[i];
}
newPath[newCount++] = str[i];
}
// write it to a different file
ofstream out("c:\\path.txt", ios::out | ios::binary);
out.write(newPath, strlen(newPath));
out.close();
Every char string in C has to end with character \0. It is an indicator that the string ends right there.
Your newPath array, after iterating through your for-loop is not correctly ended. It probably ends somewhere later, where \0 appears by accident in memory.
Try doing the following right after exiting the for-loop:
newPath[newCount]=0;
A safer way for using strings in C++, is to use std::string class over plain char arrays.
Try putting a string terminator in the buffer, after the loop :
newPath[newCount] = 0;
Related
So, I came up wit the following code to open a text file and save it in and use an array to print out all the text. My question is, how can I access a specific word or text in the file. If I am not mistaken there should be a for loop involved in this, but I am not quite sure how to go about doing it.
int main() {
ifstream dictionaryFile;
dictionaryFile.open("dictionary.txt");
char output[100];
//char wordsFromDictionary[40437][22];
int i=0;
if(dictionaryFile.is_open()){
while(!dictionaryFile.eof()){
dictionaryFile >> output;
cout<<output<<endl;
}
}
return 0;
}
If you want to read in some strings, the obvious choice would be to use std::strings to do the job. If you want an array of them, store them in an std::vector:
ifstream d("dictionary.txt");
std::vector<std::string> words{std::istream_iterator<std::string>(d), {}};
This reads all the words into the vector. If they're already sorted, you can then (for example) use std::binary_search to find whether a word is in the vector or not.
As you have a char array
char output[100];
there is no distinction between words in this data structure. File was simply read character by character and stored in the array.
A simple implementation of separation into words (using loops as you requested, with minimal changes to your code), assuming words are separated by a delimiter would be
char wordsFromDictionary[40437][22];
char delimiter=...
int i=0;
int j=0
char c;
if(dictionaryFile.is_open()){
while(!dictionaryFile.eof()){
c=dictionaryFile.get();
if(c==delimiter){
i++;
j=0;
}
else if(j<22) {
wordsFromDictionary[i][j]=c;
j++;
}
}
}
Note that this simply cuts, shortens the words that are longer than 22 chars.
I have a bit of an issue with my code. My code should be stripping all non-alphanumeric characters except .,: and ; and then sorting lines ending in dots on new lines. So, something like:
First, some characters, legal and illegal: )(=8skf-=&. This should be on a separate line. This too.
would become:
First, some characters, legal and illegal: 8skf.
This should be on a separate line.
This too.
Now, the first part of the code, which strips non-alphanumerics works perfectly. The sorting part works up to a point. So, in my code, the above line actually becomes:
First, some characters, legal and illegal: 8skf.
This should be on a separate line. This too.
I understand that this is because this is a new line and my code cannot read it in the process of becoming a new line. The code is:
int writeFinalv(string path) {
readTempFiles(path.c_str());
string line;
string nline;
int start;
int lnth;
ifstream temp("temp.txt");
ofstream final;
int length;
final.open(path.c_str(), ios::out | ios::trunc);
if(temp.is_open()) {
while(getline(temp, line)) {
length = line.length();
for(int i = 0; i < length; i++) {
if(line[i] == '.') {
if(line[i+1] == ' ') {
nline = line.substr(0, (i+2));
}
else {
nline = line.substr(0, (i+1));
}
final << nline << "\n";
start = line.find(nline);
lnth = nline.length();
line.erase(start, lnth);
}
}
}
}
else {
error = true;
}
return 0;
}
My code first works by calling the function which reads the initial file, strips it of illegal characters, and writes to a temporary file. Then, it reads the temporary file, finding dots, and writing the new lines in the initial file, after truncating it.
Thanks in advance.
By erasing part of the line string inside the for loop, the loop indexing is invalidated. Both i and length no longer hold values that you can reliably keep using to continue the for loop.
You don't actually need to erase from the string though. You can keep track of the current start position, and use that as the first parameter to the substr calls.
I'm creating a program in which I get the path of a file, then send it as a parameter into another program. The problem is when I get the path, it has the special character '\', which completely mess up the string I send to the other program. Is there a way I can ignore the escape character or change it to '/'?
Thanks!!
To change the \ to /, a simple iteration over the string should suffice. The required code is:
's' is assumed to be the concerned string.
for (int i = 0; i < s.length(); i++)
{
if (s[i] == `\`)
s[i] = `/`;
}
Please elaborate your question. The problem may be with second program.
First Program may be :
char str1[50]="start abc.exe ";
char str2[20];
cin>>str2;
strcat(str1,str2);
system(str1);
Second program may be (abc.exe) :
int main(int argc,char *argv[])
{
for(i=1;i<argc;i++)
{
cout<<argv[i]<<" \n";
}
}
This is just an example.
This may be a little bit redundant, but is there a short/compact method of reading in a string until a tab is reached in C++? Similar to other questions, but I want to keep reading even if I hit a space. For example if the STDIN is
Cute Kitty is fabulous as always
Then I want to read in Cute Kitty; is; fabulous as always, three times.
I've seen people do this with regex in files, but how would you do this on the stdin in C++? I want to put it in a string class and whenever I try something like
scanf("%s\t", &mystring);
It throws up an error because I'm not using an array of chars.
Thanks, please keep answers easy enough for a noob to understand.
This code seems to work for me. It basically gets the line that was entered from the user via stdin and then reads each character waiting for a tab character (\t), or the end of the line.
#include <iostream>
#include <string>
int main()
{
std::string a;
std::getline(std::cin,a);
int index_holder = 0;
for(std::string::size_type i = 0; i < a.size(); ++i)
{
if(a[i] == '\t' || (i == a.size() - 1)) {
std::cout << a.substr(index_holder, i - index_holder) << std::endl;
index_holder = i + 1;
}
}
return 0;
}
Have a look at strtok:
char * strtok ( char * str, const char * delimiters );
Split string into tokens. A sequence of calls to this function split str into tokens, which are sequences of contiguous characters separated by any of the characters that are part of delimiters.
I am a beginner in working with files. What I want to do in my code is to get a name from the user, and hide it in a .bmp picture. And also be able to get the name again from the file. But I want to change the characters into ASCII codes first ( that's what my assignment says)
What I tried to do is to change the name's characters to ASCII codes, and then add them to the end of the bmp picture which I'll open in binary mode. And after adding them, i want to read them from the file and be able to get the name again.
This is what I've done so far. But I am not getting a proper result. All i get is some meaningless characters. Is this code even right?
int main()
{
cout<<"Enter your name"<< endl;
char * Text= new char [20];
cin>> Text; // getting the name
int size=0;
int i=0;
while( Text[i] !='\0')
{
size++;
i++;
}
int * BText= new int [size];
for(int i=0; i<size; i++)
{
BText[i]= (int) Text[i]; // having the ASCII codes of the characters.
}
fstream MyFile;
MyFile.open("Picture.bmp, ios::in | ios::binary |ios::app");
MyFile.seekg (0, ios::end);
ifstream::pos_type End = MyFile.tellg(); //End shows the end of the file before adding anything
// adding each of the ASCII codes to the end of the file.
int j=0;
while(j<size)
{
MyFile.write(reinterpret_cast <const char *>(&BText[j]), sizeof BText[j]);
j++;
}
MyFile.close();
char * Text2= new char[size*8];
MyFile.open("Picture.bmp, ios:: in , ios:: binary");
// putting the pointer to the place where the main file ended and start reading from there.
MyFile.seekg(End);
MyFile.read(Text2,size*8);
cout<<Text2<<endl;
MyFile.close();
system("pause");
return 0;
}
Many flaws are in your code, one important is:
MyFile.open("Picture.bmp, ios::in | ios::binary |ios::app");
Must be
MyFile.open("Picture.bmp", ios::in | ios::binary |ios::app);
^ ^
| |
+-----------+
Second, use std::string instead of C-style strings:
char * Text= new char [20];
should be
std::string Text;
Also, use std::vector to make a array:
int * BText= new int [size];
should be
std::vector<int> BText(size);
And so on...
You write int (which is 32 bits) but read char (which is 8 bits).
Why not write the string as-is? There's no need to convert it to an integer array.
And also, you don't terminate the array you read into.
your write operation is incorrect, you should pass the complete text directly
MyFile.write(reinterpret_cast <const char *>(BText), sizeof (*BText));
Also, casting your string to ints and back to chars will insert spaces between your characters which you don't take into account in your reading operation