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 5 years ago.
Improve this question
I am writing a program to convert numbers from decimal to binary. I already have the algorithm correct for it and the program works fine while using cout. However, as soon as I use outfile in my loop the program crashes with error code (0xC0000005).
Here is my source code:
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cmath>
using namespace std;
int main()
{
int num, remainder_count;
ifstream infile; //define new input file stream
ofstream outfile; //define new output file stream
infile.open("C:\\Users\\Arctic-Gaming\\CLionProjects\\working\\Source\\Binary Conversion (Loop w File)\\Binary Input.txt"); //connect the stream to an actual file
if (!infile)
{
cout << "Cannot open input file! Program aborted" << endl;
return 1;
}
outfile.open("C:\\Users\\Arctic-Gaming\\CLionProjects\\working\\Source\\Binary Conversion (Loop w File)\\Decimal Output.txt"); //connect the stream to an actual file
do
{
int remainder [15] = {0};
remainder_count = 15;
infile >> num;
outfile << "\n" << num << endl;
if (num > 0 && num <= 65535)
{
while (num > 0)
{
remainder[remainder_count] = num % 2;
num /= 2;
remainder_count--;
}
remainder_count = 0;
while (remainder_count < 16)
{
if (remainder_count % 4 == 0)
{
outfile << " ";
}
outfile << remainder[remainder_count];
remainder_count++;
}
}
else if (num == 0)
outfile << "0000 0000 0000 0000" << endl;
else
cout << "Error! Invalid Input." << endl;
}
while (!infile.eof());
}
Your program has undefined behavior by accessing an element out-of-bounds. Since the behavior is undefined, the issue really has nothing to do with using std::cout as opposed to using file streams.
int remainder [15] = {0};
//...
remainder_count = 15;
//...
remainder[remainder_count] = num % 2; // out-of-bounds access (remainder[15] is out-of-bounds)
Once that line above is executed, all bets are off as to how your program will behave. The valid indices of an array range from 0 to n-1, where n is the number of elements in the array. So the valid indices are 0, 1, 2, up to 14 for the remainder array.
If you had switched to using std::array instead of regular C++ arrays, instead of undefined behavior, you would get an std::out_of_range exception thrown as soon as you access that element using at().
std::array<int, 15> remainder= {{0}};
remainder_count = 15;
//...
if (num > 0 && num <= 65535)
{
while (num > 0)
{
remainder.at(remainder_count) = num % 2; //... exception thrown
Live Example
So as you see, your program never "ran fine" as you claimed, and you will have to fix your program so that you are not going out-of-bounds of your array.
Related
Sorry for the somewhat beginner question, but I've been at this for a couple of days and can't figure out a solution.
I'm basically reading integers from a file, these files should have a set amount of numbers, for the purpose of this question let us say 40. I can return an error fine when the file has less than or more than 40 integers. However, if there happens to be a non-numeric character in there, I'm struggling to figure out how to return an error.
This is what I'm currently doing:
int number = 0;
int counter = 0;
while(inputstream >> number)
{
// random stuff
counter++;
}
if (counter < 40)
return error;
It is at this point I'm a bit confused where to go. My while loop will terminate when the input stream is not an int, but there are two cases when this could happen, a non-integer character is in there, or the end of file has been reached. If we're at eof, my error message is fine and there were less than 40 integers. However, we could also be at less than 40 if it encountered a non-int somewhere. I want to be able to determine the difference between the two but struggling to figure out how to do this. Any help would be appreciated. Thanks!
you can input a line inside loop and try to convert it to integer so if the conversion fails means a non-integer and immediately break the loop returning a error telling that a non-integer found.
otherwise continue read until the end of file then check whether values are less or more 40 checking whether the loop reads all the content or broke because of non-integer value:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
enum ERRORFLAG{INIT, LESS_40, MORE_40, NON_INT}; // enumerate error
int main()
{
ifstream in("data.txt");
string sLine; // input one line for each read
int value; // value that will be assigned the return value of conversion
int count = 0; // counter for integer values
ERRORFLAG erFlag = INIT; // intialize the error flag
while(getline(in, sLine)) // iterate reading one line each time
{
if( !(value = atoi(sLine.c_str()) ) ) // conversion from string to integer so if the conversion failed else body will be executed
{
erFlag = NON_INT; // setting the error flag to non-int and break
break;
}
else
count++; // otherwise continue reading incrementing count
}
if(INIT == erFlag) // check whether the loop finishes successfully or a non-int caused it to break
{
if( count < 40) // checking whether number of ints less than 40
erFlag = LESS_40; //
else
if(count > 40) // or more than 40
erFlag = MORE_40;
}
// printing the error
switch(erFlag)
{
case LESS_40:
cout << "Error: less than 40 integers << endl";
break;
case MORE_40:
cout << "Error: More than 40 integers << endl";
break;
case NON_INT:
cout << "Error: non-intger found!" << endl;
break;
default:
cout << "Undefined Error" << endl;
}
in.close();
std::cout << std::endl;
return 0;
}
#include <iostream>
using namespace std;
int main() {
int count = 0;
int x;
istream& is = cin; // works with every class that inherits this one
while (is >> x) ++count;
if (is.eof()) {} // end of file reached
else {} // a bad value has been read
cout << "Read count " << count << '\n';
}
this program works fine: first read the file checking for a non-digits and non-white space characters and if you find break immediately setting the error flag.
keep in mind that white spaces like single and tab space will not be considered as invalid because they are used in your file as separators so any character other than digit or white space will break the loop returning an error.
if no error occurred (no invalid character found) and reaching the end of file then read again the file pushing the integer values into a vector which is a good idea without needing a counter then check the size of vector if it is less or more than 40 issuing an error otherwise print the content of vector:
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
#include <vector>
enum ERRORFLAG{INIT, LESS_40, MORE_40, NON_INT};
int main()
{
ifstream in("data.txt");
char c;
string sLine;
int value;
vector<int> vec;
ERRORFLAG erFlag = INIT;
while(in >> c)
{
if(!isspace(c) && !isdigit(c))
{
erFlag = NON_INT;
break;
}
}
in.clear();
in.seekg(0, ios::beg); // jumping back the the beginning of the file moving the get pointer to the beginning
while(in >> value)
vec.push_back(value);
if(NON_INT == erFlag)
cout << "non-int found!" << endl;
else
{
if(vec.size() < 40)
cout << "les than 40 integers!" << endl;
else
if(vec.size() > 40)
cout << "more than 40 integers found!" << endl;
else
for(int i(0); i < vec.size(); i++)
cout << vec[i] << ", ";
}
std::cout << std::endl;
return 0;
}
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 6 years ago.
Improve this question
my c++ program is working ambiguously.number is automatically changing into hexadecimal..please help
int main() {
int t=0;
cin>>t;
while(t--)
{
int Q;
string A,B,C;
cin>>Q;
cin>>hex>>A;
cin>>hex>>B;
cin>>hex>>C;
string bit_A,bit_B,bit_C;
bit_A=con(A);
bit_B=con(B);
bit_C=con(C);
int k=0;
for(unsigned i = 0; i != bit_B.length(); ++i)
{
if(bit_B[i]=='0' && bit_C[i]=='1' && bit_A[i]=='0' )
{
bit_B[i]='1';
k++;
continue;
}
if(bit_C[i]=='0')
{
if(bit_B[i]=='1')
{
bit_B[i]='0';
k++;
}
if(bit_A[i]=='1')
{
bit_A[i]='0';
k++;
}
continue;
}
}
if(k>Q)
{
cout<<"-1";
continue;
}
cout<<"value 0f k is"<<k<<endl;
for(unsigned i = 0; k<Q && i != bit_A.length(); ++i)
{
if(bit_A[i]=='1' && bit_B[i]=='1')
{
bit_A[i]='0';
k++;
}
if(bit_A[i]=='1' && bit_B[i]=='0' && (Q-k)>=2)
{
bit_A[i]='0';
bit_B[i]='1';
k++;
k++;
}
}
}
cout<<std::uppercase<<hex<<todeci(bit_A)<<endl;
cout<<std::uppercase<<hex<<todeci(bit_B)<<endl;
}
return 0;
}
here k value hacve changed automatically to hexa decimal which i cant figure out y?can anyone please help?
1
12
CAF7028FD
59B5AC1CE
CAF1B7B7F
for this input you will see k showing as B in output
If you pass std::hex to a stream, it tells that stream to read or write numerical data as hexadecimal numbers.
cout << hex << 16 << endl;
// Outputs "10".
int i;
cin >> hex >> i;
// If you enter "10", reads "16".
If you want to switch the stream back to decimal, pass it std::dec, like so:
int j = 0x10; // 16
cout << dec << i << endl;
// Outputs "16".
int k;
cin >> dec >> k;
// Reads "10" as "10".
You can also do this for octal (base-8), using std::oct. This follows the same rules as the above two modifiers.
Note that after passing a modifier to a stream, it will retain that state until passed another modifier.
int x = 0xFF; // 255
int y = 0x3E; // 62
cout << hex << x << endl; // Outputs "FF".
int z;
cin >> z;
cout << y << endl; // Outputs "3E".
cout << dec << x << endl; // Outputs "255".
cin >> z;
cout << y << endl; // Outputs "62".
Notice that both times y was output to cout, it used the same formatting that was specified before outputting x, instead of reverting back to decimal output. Due to this, if you want to output a single value as hexadecimal, and later values as decimal, it can be useful to write it like this:
cout << hex << 16 << dec << endl;
Note that there is no associated modifier for binary output. If you want to output a number in binary, the simplest way is to create and output a temporary std::bitset, like so:
#include <bitset> // For std::bitset.
#include <climits> // For CHAR_BIT.
unsigned int q = 0xF3;
cout << bitset<sizeof(unsigned int) * CHAR_BIT>(i) << endl;
// Outputs "00000000000000000000000011110011".
Similarly, if you want to read a binary number, you can use std::bitset like so:
unsigned int r = 0;
std::bitset<sizeof(unsigned) * CHAR_BIT> bitReader;
cin >> bitReader;
r = static_cast<unsigned>(bitReader.to_ulong());
// Reads binary value, then converts it to an unsigned integer type.
Note that CHAR_BIT is the system's byte size; as such, multiplying by CHAR_BIT isn't strictly necessary (it's usually safe to assume it's 8 bits), but will make your code more portable (by allowing it to compile properly on systems where the byte size isn't 8 bits).
This question already has answers here:
Why is iostream::eof inside a loop condition (i.e. `while (!stream.eof())`) considered wrong?
(5 answers)
Closed 8 years ago.
My program is all running fine except that it is reading a seemingly random seven-digit number at the end of the file to add an additional number to the file and I have not been able to figure out why. I was able to determine that it has something to do with the first while() loop.
I have tried everything I can think of and one thing I have noticed is that when I change the global variable to the number of numbers I know are in the file (12) it will work perfectly. However, I am suppose to do this so that I do not know exactly how many numbers are in the file.
What the output in the new file is suppose to look like but with the extra number:
8
10
12
17
25
36
47
62
62
65
87
89
2972880 //However this last seven digit number is not suppose to be there...here is the code...
#include <iostream>
#include <fstream>
using namespace std;
const int SIZE = 256;
int main(void)
{
int getNumbers[SIZE];
ofstream outFile;
ifstream inFile;
bool success;
int count = 0,
total = 0,
add = 1;
int num;
inFile.open("numbers.txt");
if (inFile.is_open())
{
cout << "File successfully read." << endl;
}
while (count < (total + add) && !inFile.eof())
{
inFile >> getNumbers[count];
total += add;
count++;
}
int grandTotal = (total - 1);
do
{
success = false;
for (int i = 0; i < grandTotal; i++)
{
if (getNumbers[i] > getNumbers[i + 1])
{
num = getNumbers[i];
getNumbers[i] = getNumbers[i + 1];
getNumbers[i + 1] = num;
success = true;
}
}
grandTotal--;
} while (success);
inFile.close();
outFile.open("sorted.txt");
if (outFile.is_open())
{
cout << "File successfully opened." << endl;
}
int index = 0;
while (index < total)
{
outFile << getNumbers[index]
<< " \n";
index++;
}
outFile.close();
return 0;
}
As #Galik pointed out, you shouldn't check for eof() in a loop condition, because it will always give you one garbage data point at the end. Move the read into the loop condition.
while (count < (total + add) && inFile >> getNumbers[count])
{
total += add;
count++;
}
Before we start, yes this is homework, no i'm not trying to get someone else to do my homework. I was given a problem to have someone enter a binary number of up to 7 digits and simply change that number from binary to decimal. Though i'm most certainly not using the most efficient/best method, i'm sure I can make it work. Lets look at the code:
#include <iostream>
#include <math.h>
using namespace std;
int main() {
char numbers[8];
int number = 0, error = 0;
cout << "Please input a binary number (up to 7 digits)\nBinary: ";
cin.get(numbers, 8);
cin.ignore(80, '\n');
for (int z = 7; z >= 0; z--){}
cout << "\n";
for (int i = 0, x = 7; x >= 0; x--, i++){
if (numbers[x] <= 0){ // if that is an empty space in the array.
i--;
}
else if (numbers[x] == '1'){
number += pow(2, i);
}
else if (numbers[x] != '0'){ // if something other than a 0, 1, or empty space is in the array.
error = 1;
x = -1;
}
}
if (error){ // if a char other than 0 or 1 was input this should print.
cout << "That isn't a binary number.\n";
}
else{
cout << numbers << " is " << number << " in decimal.\n";
}
return 0;
}
If I run this code it works perfectly. However in a quick look through the code there is this "for (int z = 7; z >= 0; z--){}" which appears to do absolutely nothing. However if I delete or comment it out my program decides that any input is not a binary number. If someone could tell me why this loop is needed and/or how to remove it, it would be much appreciated. Thanks :)
In your loop here:
for (int i = 0, x = 7; x >= 0; x--, i++){
if (numbers[x] <= 0){ // reads numbers[7] the first time around, but
// what if numbers[7] hasn't been set?
i--;
}
you are potentially reading an uninitialized value if the input was less than seven characters long. This is because the numbers array is uninitialized, and cin.get only puts a null terminator after the last character in the string, not for the entire rest of the array. One simple way to fix it is to initialize your array:
char numbers[8] = {};
As to why the extraneous loop fixes it -- reading an uninitialized value is undefined behavior, which means there are no guarantees about what the program will do.
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
For some reason, the code just crashes and gives me an Access Violation error. It keeps saying the object users is not initialized.
First-chance exception at 0x0F45E89A (msvcr110d.dll) in Random Coding
in C++.exe: 0xC0000005: Access violation writing location
0xABABABAB.Unhandled exception at 0x0F45E89A (msvcr110d.dll) in Random
Coding in C++.exe: 0xC0000005: Access violation writing location
0xABABABAB.
Thanks. Any ideas?
#include <iostream>
#include <fstream>
#include <cstring>
#include <sstream>
#include <vector>
#include <string>
using namespace std;
struct User {
string name; //Both first and last name go here
int birthYear;
string major;
};
int main()
{
ifstream input("input.txt");
if(!input || !input.is_open())
return -1;
string buffer;
int count = -1;
int index = 0;
int size;
User* users;
while(getline(input, buffer, '\n'))
{
stringstream ss(buffer);
if(count == -1)
{
ss >> size;
users = new User[size];
count = 0;
}
else
{
if(count == 0)
{
users[index].name = buffer;
count++;
}
if(count == 1)
{
ss >> users[index].birthYear;
count++;
}
if(count == 2)
{
users[index].major = buffer;
count = 0;
index++;
}
}
}
for(int i = 0; i < 2; i++)
{
cout<<users[i].name << " " << users[i].birthYear << " " << users[i].major <<endl;
}
system ("PAUSE");
return 0;
}
for(int i = 0; i < 2; i++)
{
cout<<users[i].name << " " << users[i].birthYear << " " << users[i].major <<endl;
}
Looks incoorect. How are you so sure that users contain atleast two elements. If getline fails because of badfile or first line suggests only 1 record, you will get above exception.
You should change the loop to
// Initialize size with 0 before while(getline) loop
for(int i = 0; i < size; i++)
{
cout<<users[i].name << " " << users[i].birthYear << " " << users[i].major <<endl;
}
Also below lines of code look problematic
if(count == 0)
{
users[index].name = buffer;
count++;
}
if(count == 1)
{
ss >> users[index].birthYear;
count++;
}
if(count == 2)
{
users[index].major = buffer;
count = 0;
index++;
}
When count is 0, it would go into first if condition and get incremented. Then condition count == 1 would become true and you will visit next 2 conditions also. You should replace next 2 if conditions with else if or a switch with break statements to see the intended behavior.
Also it would be a good practice to free users after you are done with it.
What I think is that the first getline fails (the while does not enter, so nothing is created) and you automatically reach the for loop. Check in the for that you actually have users.