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 4 years ago.
Improve this question
I'm sorry. I'm a bit new here and I'm not really sure where to post it. But I'm making a packet parser.
The program is suppose to open a file(that is in binary string) and then convert it into numbers(for the IP) and letters( the poem lines itself)
I'm stuck at my string function which takes a string from the file and then converts it into a sentence. I tested my binary to ascii converter and it works fine. I also tested returning a set string("string line=" banana") in my string poem_line function and it returns it just fine too.
I also tested the loop and it prints the binary string of the line needed to be changed just right.
I don't know what else is wrong.
string poem_Line(int packe,int datal, char p){
int m=0;
int start_where=0;
string line;
string transformed;
start_where=packe-datal; //this is the 32+32+16+16+16
ifstream inFile_data("cases_random.in");
if(inFile_data.is_open()){
for(m=0; m<packe; m++){
inFile_data>>p;
if(m>=start_where){
int q=0;
line[q]=p;
q++;
}
}
inFile_data.close();
transformed=binaryAscii(line);
}
else
cout<<"is not open"<<endl;
return transformed;
}
full code!
This line:
string line;
Creates an empty string.
This line:
line[q]=p;
Tries to write to string at position that is not allocated (memory you don't own, and your string object would not know about because its managed string size is 0. This is undefined behaviour)
I suggest you .resize() your string after creation, if you know target size, or simply use += p to add chars to it:
line += p;
Your line length equals to zero. Do line.push_back(p); instead of line[q]=p;. push_back resizes string and increase its length. line[q]=p; - in this case you are writing to another memory which doesn't belong to line, you can rewrite something important data by your overwriting.
Related
This question already has answers here:
What is an off-by-one error and how do I fix it?
(6 answers)
Closed 1 year ago.
I came across a scenario where string concatenation is failing in C++. But I don't see a reason for it to fail.
Code sample is as below:
int main()
{
std::string a;
std::string b = "bbbbbbb";
a.resize(10);
for (int i = 0; i <= 5; i++) {
a[i] = 'a';
}
a = a+b;
printf("\n%s\n", a.c_str());
}
It is outputting aaaaaa.
I was expecting it to output aaaaaabbbbb. If I change a.resize(10); to a.resize(5); I am getting the expected output.
Would be helpful if someone could help me in understanding the behaviour?
In addition to the off-by-one error, after concatenation, the contents of a in main are:
aaaaa\0\0\0\0\0bbbbb
So: five 'a' bytes, then five zero bytes, then five 'b' bytes. The string is fifteen bytes long.
printf, like other C functions, doesn't know about this size, and instead takes the length of the string to be until the first zero byte. In your case, that is "aaaaa".
To print the entire string, use something like std::cout. If you're certain you want printf, it is also possible to pass a length to that with the %.*s specifier.
std::string a;
a.resize(10);
gives you a string of size 10 but whose content is undefined.
You set the first 5 character to something specific and append some more characters to the end. But characters 5-10 never get set to something.
In the execution you are seeing, these characters happen to be zero, but printf – as a C style function — considers the appearance of a null character the end of the string. Therefore it stops printing.
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 2 years ago.
Improve this question
I am writing a simple C ++ program as my homework to count the number of numbers in a text file. Below is my code, but unfortunately it counts words and numbers. I have no idea how it should count the number of numbers, where is the error?
My text file:
lorem ipsum 5 87 451 13
My code:
#include <iostream>
#include <cstdio>
#include <fstream>
using namespace std;
int main()
{
int n=0;
char plik[100], liczby[100];
string nazwapliku;
nazwapliku="file.txt";
ifstream we("file.txt");
if (!we)
{
cout<<"Can't read file'";
cin.ignore();
getchar();
return 1;
}
while (!we.eof())
{
we>>liczby;
if(we)
n=n+1;
}
we.close();
cout<<"Numbers count in "<<nazwapliku<<" : "<<n;
getchar();
return 0;
}
Let's start off with two very important things which apply to all programs you are going to write:
Never ever read unconstrained into a buffer - ever! That is the primary attack vector for hackers trying to subvert your program by overwriting what comes after buffer. Always limit the input the maximum space allowed, e.g., setting up the width of the buffer using std::setw(liczby). In nearly all cases in C++ you'd want to use std::string instead of a fixed size character buffer. These don't have problem of buffer overruns (it may still be desirable to limit the maximum amount of space they take which can be done with allocators).
Always test whether input was successful before you use the input. Doing so does not involve stream.eof() as that condition only holds when the program has exhausted all input. Also you need to check after reading (as the loop isn't written idiomatic, I didn't notice that you actually do check if (we); it is worth writing the loop idiomatic, though). For example, your loop could reasonably look like (if it weren't for the second point):
while (we >> std::setw(sizeof(liczby) >> liczby) {
// ...
}
As your program only tries to read words, it obviously only counts the number of words. To count "numbers" which seem to be sequences of digits for your assignment you'll need check whether a given word consists of only numbers (and in case you are trying to use std::isdigit() from <ccctype> please be aware that this function only accepts positive int while char is normally signed, i.e., you'd need to cast your char to unsigned char before feeding them into std::isdigit()). I leave the actual implementation as an exercise, though.
This question already has answers here:
I can't double characters inside string with function
(3 answers)
Closed 2 years ago.
currently learning strings, i have the following:
string s;
s[0]='a'; s[1]='b';
cout<<s;
string s; s.clear();
s+='a'; s+='b';
cout<<s;
I get empty string as output from 1st example, and the 2nd works fine. I get that the 1st is undef behavior and that we 'push' an element the second time instead of assigning a value.
Any more clarification will be appreciated
string s;
creates empty string
s[0]='a'; s[1]='b';
this is undefined behavior, since empty string have size zero, so required buffer may not exists.
It "works" since all major compilers are using Small String Optimization (SSO). In this optimization size of string object, allows to keep small string inside that object not on a heap. As a result minimum capacity of std::string is none zero (15 in gcc if I remember correctly).
cout<<s;
Now deeding on how this stream operator is implemented it can print empty string (size size of string is zero) or "ab" or "ab<some thrash>".
On gcc it prints nothing.
To fix it you can:
resize string first s.resize(2)
use push_back API
I am learning data file handling basics in c++ (and am working in the compiler turbo C++).
So I wanted to create a text file , write some data onto it and then read it.
So I wrote this: -
int main()
{
fstream fin;
fin.open("textfile.txt",ios::in|ios::out);
for(int i=0;i<3;i++)
{
char x;
cin>>x;
fin<<x;
}
fin.seekg(0,ios::beg); //I added this and also tried seekp() when I didn't get the desired output
//but to no use
while(!fin.eof())
{
char v;
fin>>v;
cout<<v;
}
fin.close();
getch();
return 0;
}
But instead of outputting only the 3 characters which I input, it outputs 4 characters.
I tried removing the loops and taking input and giving outputs one by one like this (among other things):
...
char x,y,z;
cin>>x>>y>>z;
fin<<x<<y<<z;
fin.seekg(0,ios::beg);
char q,w,e;
fin>>q>>w>>e;
cout<<q<<w<<e;
...
But it still didn't work.
I think it has something to do with file pointers and their location but don''t know what. I tried finding a similar question on the net but to no avail.
So I want to know what is wrong with what I did and how to I improve this to actually write and read in a file sequentially using the same file object (if it is even possible). And is seekg() even necessary here?
Thanks.
The problem you face is a general problem. Your input code is right and there is no error in that. The problem is your ouput code and to be more specific the line while(!fin.eof()). eof(end-of-file) works on a end of file mark whose numeric value is generally -1. But this function goes false only when the end character is encountered and traversed. To remove this error just replace this statement with a read statement that is move this line fin>>v from loop statements to the conditional statements. In this false will be when it encounters a end character.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
void insert_into_stream(std::ostream& stream, int number)
{
int length = sizeof(int);
char insert_buffer[sizeof(int)];
memcpy(insert_buffer, &number, length);
stream.write(insert_buffer, length);
}
int int_from_string(std::string string)
{
int a;
std::istringstream(string)>>a;
return a;
}
This code used to work before, I don't remember what slight change I did and it isn't working anymore.
When a number (for example, 8001) comes in, and I'm debugging just before the last statement, insert_buffer contains 'A', so obviously something is going wrong and the 2nd function doesn't retrieve 8001.
Note - I do convert the stream to a string before sending it to the 2nd function.
Where is the first function wrong?
---edit----
Yes, I was wrong, the first function is actually doing exactly what it should, the second is wrong, can anyone please fix that?
These two functions are doing completely different things.
The first function is writing out the raw binary representation of an integer to a stream.
You have just copied the bits, this is the correct thing to do if you are serialising out to a binary file.
To convert it back, you would have to read in those 4 bytes, and cast that into an integer, just like you're doing the other way round.
Of course when you examine the characters they're going to be a one byte ascii representation of the integer bits. So 'A' is a perfectly reasonable thing to be there, as is anything else as it is entirely meaningless.
The second function however, is doing an ASCII Number to Integer number conversion. i.e. atoi. This is meaningless for what you're trying to do as the characters aren't ascii numbers, they're binary integer numbers.
Edit for edit: You want something like this, just the opposite of what you did above.
int int_from_string(const char* number)
{
int a;
memcpy(&a, number, sizeof(int));
return a;
}
Try to use
stream.write((const char*)&number, sizeof(number));
It's much shorter and you can also change the type of number and it will work (For simple types).