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).
Related
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 1 year ago.
Improve this question
I need matrix of characters to save 'n' subject (some subjects have 3-4 words). The user will enter 'n' number of subjects and names of subjects. I can only use CHAR, not STRING or VECTOR.
#include <iostream>
using namespace std;
int main() {
int n;
cin>>n;
char matrix[n][100];
for(int i=0; i<n; i++) {
cin.getline(matrix[i][100]);
}
}
First problem with your code is that you are trying to make a variable size array with static allocation which C++ won't like (your n varies and you are trying to make char matrix[n][100]). You will need to use dynamic allocation for that.
Second problem is that getline requires an additional parameter to work (max number of characters per word you can take in, which is in your case 100).
And the third problem is that you are trying to put a whole word into a place for a single character in cin.getline(matrix[i][100]);. I'm not sure you understand why are you exactly making a matrix[n][100] so I will briefly explain.
One char stores a single character, like 'a'.
char oneCharacter = 'a';
To make a word out of those you would want few characters, so you make an array of characters. In the example I made an array of character which can take up to 5 of them.
char multipleCharacters[5];
And now you want to store a few words, so you make an array of array of characters. In the example I made an array of array of characters which can take up to 10 words of 5 characters. To make an array which size you are going to input, look up dynamic allocation from the first part of my answer.
char multipleWords[10][5];
Knowing this, can you figure out whats wrong with cin.getline(matrix[i][100]);?
As I said in a comment earlier, this is a terrible assignment. You are being asked to do several things in "odd" ways, not using and learning best practices for writing code.
My advice in general: start by separating the input, output, and "work".
Let's suppose that the code for the real lesson here is all in the "work" part. There are indeed many reasons for learning to manipulate memory this way, and C++ for writing low-level, system, or efficient code is a major part of the craft.
So, you want to arrange n words into a 2-D array of characters. Focus on (just) that, by passing in the data to be so-arranged using normal C++ code. Abstract it as a class to hold the data. Maybe this is the binary image to send to a dumb LCD on a keosk, or label printer? There may be a real reason to do something like this.
Putting in a class you can make sure memory is freed correctly; normally you want no naked new's in your code, and will use existing container types rather than low-level memory. Here, we'll use a unique_ptr of rows.
class project {
static constexpr size_t rowlen = 100;
using row = char[rowlen];
std::unique_ptr<row[]> matrix;
public:
void layout (const vector<string>& inputs);
// todo.. provide a good way to access the data
};
Now don't worry about reading from the user, especially reading directly into an odd format! That just makes this extra challenging for no reason. Take the data (presented in a normal easy-to-use way) and concentrate on doing the low-level memory manipulation chore: Allocate input.size() rows, and for each input string clamp to the maximum length and copy the characters into one row (what about the rest of the chars? Assume should be space or what?)
Clamp the length using std::max. Copy the actual characters using std::copy.
Something like this (untested; just off the top of my head):
void project::layout (const vector<string>& inputs)
{
constexpr auto N = input.size();
matrix = new row[N];
for (const size_t i= 0; i < N; ++i) {
const auto len = std::max(input[i].size(), rowlen);
auto& dest = matrix[i]; // alias the whole row
char* p= &dest[0]; // pointer to first char in the row
std::copy_n (input[i].data(), len, p);
std::fill_n (p+len, rowlen-len, ' ');
}
}
See https://en.cppreference.com/w/cpp/algorithm for details on the std algorithms. Keep that site bookmarked; it is a great way to look things up while you write code.
To do this, you need to understand how pointers work in C (and thus in C++). Also, how the same "place" can be different types: A pointer to the whole row is the same address as the first character of that row, but they are different types. So do things a little piece at a time, just as with the earlier definition of matrix.
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.
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.
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
I have been looking and I have not found anything on scanf that really helps me. I am completly new to this and was hoping for help on reading a string with scanf. The first thre numbers can be any digits. I was attempting to read them into a variable int. the last one in the string is a char. this is my string
(1,2,123, 0)
(1,2,1,s)
This is my code:
int i,j,k;
char c, final;
scanf ("%c", c, "%d",&i, "%c", c, "%d", &j, "%d",&k, "%c", final);
I know this is not right but any help is appreciated
If the first 3 are digits and the last one is a character and are seperated by a space,which you want to assign to 3 integer variables and a character variable, use scanf like this:
int a,b,c;
char ch;
scanf ("%d%d%d %c",&a,&b,&c,&ch);
Or else if you want to extract 3 integers and a character from a string , use sscanf. It is not possible to do it with scanf.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question appears to be off-topic because it lacks sufficient information to diagnose the problem. Describe your problem in more detail or include a minimal example in the question itself.
Closed 8 years ago.
Improve this question
recently I made a program that, given a string, the function returns its corresponding ascii code. For example, the string "h", the function returns an int 104. Now, I want to do the reverse process, ie, given an int, return its corresponding ascii character. For example, given the 104 int return the string "h". Please, help.
Looking at the string constructors, we can see one that takes a count and a character value. So we can use that:
return std::string(1, ascii_value);
You probably don't need a whole string for this. Given that you're looking for a single character, the correct type to use is a char:
int x = 65;
char xc = (char)x;
assert(xc == 'A');
char c;
...
std::string mystring(1, c);