C++ file writing/reading - c++

I'm trying to create an array, write array to the file and than display it. It seems to be working but i get just part of the output (first 3 elements) or i get values over boundaries.
#include <iostream>
#include <fstream>
using namespace std;
int main()
{
int arr[20];
int i;
for (i = 0; i < 5; i++)
{
cout << "Enter the value to the array: " << endl;
cin >> arr[i];
}
ofstream fl("numbers.txt");
if (!fl)
{
cout << "file could not be open for writing ! " <<endl;
}
for (i = 0; i < arr[i]; i++)
{
fl<<arr[i]<<endl;
}
fl.close();
ifstream file("numbers.txt");
if(!file)
{
cout << "Error reading from file ! " << endl;
}
while (!file.eof())
{
std::string inp;
getline(file,inp);
cout << inp << endl;
}
file.close();
return 0;
}

The terminating condition in the for loop is incorrect:
for(i=0;i<arr[i];i++)
If the user enters the following 5 ints:
1 0 4 5 6
the for loop will terminate at the second int, the 0, as 1 < 0 (which is what i<arr[i] would equate to) is false. The code has the potential to access beyond the bounds of the array, for input:
10 11 12 13 14
the for loop will iterate beyond the first 5 elements and start processing unitialised values in the array arr as it has not been initialised:
int arr[20];
which could result in out of bounds access on the array if the elements in arr happen to always be greater than i.
A simple fix:
for(i=0;i<5;i++)
Other points:
always check the result of I/O operations to ensure variables contain valid values:
if (!(cin >> arr[i]))
{
// Failed to read an int.
break;
}
the for loop must store the number of ints read into the arr, so the remainder of the code only processes values provided by the user. An alternative to using an array, with a fixed size, and a variable to indicate the number of populated elements is to use a std::vector<int> that would contain only valid ints (and can be queried for its size() or iterated using iterators).
while (!file.eof()) is not correct as the end of file flag will set only once a read attempted to read beyond the end of the file. Check the result of I/O operations immediately:
while (std::getline(file, inp))
{
}

its like hmjd said
for(i=0;i<arr[i];i++)
looks wrong
it should look like this
int size;
size=sizeof(your array);
for(i=0;i<size;i++)

Try this:
//for(i=0;i<arr[i];i++)
for(i=0;i<5;i++)
[EDITED]
I would initialize the array with 0 like this: int arr[20] = {0}; In this case you can use for example:
while ((arr[i] != 0 || i < sizeof(arr))

i<array[i]
It is wrong beacuse it comapres with the content of the array ,it does not check the size of array .

Related

Exception case: checking to see if the element already exists in an array c++

I'm currently learning c++. I got stuck in this little problem with the exception.
A program asks users to enter 5 integers in an array. I need the program to manage an exception that requests the input of an element again if it already exists.
Here is my code, I figured out the global structure, but the problem is if you enter 0 the program will throw out an exception "already exists", that's not the result I wanted. I know where this comes from, T[j] was not defined in for loop, but I don't know how to deal with it. Could anyone help me to improve it, please? other solutions are also welcomed.
#include<iostream>
#include <vector>
#include<cstdlib>
using namespace std;
int main(){
int i=0,j=0;
int temp;
vector<int>T(5);
do{
try{
cout<<"user input "<<(i+1)<<":";
cin>>temp;
//T[j]= 'a000000000000000000'; //I tried to define T[j], that's maximum I can do
for(j=0;j<=i;j++){
if(T[i]==T[j])
throw(0);
}
T[i]=temp;
i++;
}
catch(const int){
cout<<"Error: value already exists, try again"<<endl;
}
} while(i<sizeof(T)/sizeof(int));
for(i=0;i<sizeof(T)/sizeof(int);i++){
cout<<T[i]<<endl;
}
return 0;
}
This line creates a vector which contains 5 ints. All ints in the vector are zero:
vector<int>T(5);
This line runs a loop. Since i is zero, it runs the loop one time, where j is equal to zero, because j<=i is true, because both of them are zero.
for(j=0;j<=i;j++){
This line checks whether T[i] equals T[j], which it does, because i and j are both zero, and T[0] equals T[0].
if(T[i]==T[j])
This line throws an exception.
throw(0);
Did you spot the bug yet? Maybe you don't want to run the loop where j is equal to i. Maybe you want to loop while j<i instead of j<=i. So if i is 5, j goes from 0 to 4 instead of 0 to 5, and if i is 0, the loop does not run at all.
Also, as Mark Ransom pointed out, this is wrong:
sizeof(T)/sizeof(int)
It should be
T.size()
sizeof(T)/sizeof(int) would work for an array, but not for a vector. You want T.size() instead.
If there isn't a requirement for the numbers to be output in the same order as they were input, a std::set (or std::unordered_set) would work well
#include <iostream>
#include <set>
int main()
{
constexpr int NUMBERS_TO_READ{5};
std::set<int> numbers;
int i = 0;
do
{
int temp;
std::cout << "user input " << (i+1) << std::endl;
std::cin >> temp;
if (numbers.find(temp) != numbers.end())
{
//temp is already in the set
std::cout << "Value " << temp << " already exists, try again!" << std::endl;
}
else
{
//temp isn't in the set. add it.
numbers.insert(temp);
i++;
}
}
while (i < NUMBERS_TO_READ);
for (const auto num : numbers) std::cout << num << std::endl;
}

Reading space separated input into an array in C++

What is the easiest way to read space separated input into an array?
//input:5
1 2 3 4 7
int main() {
int n;
cin>>n;
int array[n];
for (int i =0;i<n;i++){
cin>>array[i];
}
cout<<array;
return 0;
}
I tried the code above but the output is 0x7ffe42b757b0.
The problem lies with your printing. Since array is a pointer, you are only printing an address value.
Instead, do this:
for (int i =0;i<n;i++){
cout<< array[i] << " ";
}
You can do that by passing std::istream_iterator to std::vector constructor:
std::vector<int> v{
std::istream_iterator<int>{std::cin},
std::istream_iterator<int>{}
};
std::vector has a constructor that accepts 2 iterators to the input range.
istream_iterator<int> is an iterator that reads int from a std::istream.
A drawback of this approach is that one cannot set the maximum size of the resulting array. And that it reads the stream till its end.
If you need to read a fixed number of elements, then something like the following would do:
int arr[5]; // Need to read 5 elements.
for(auto& x : arr)
if(!(std::cin >> x))
throw std::runtime_error("failed to parse an int");
array variable always give base address of an array
for (int i =0;i<n;i++){
cout<< array[i] << " ";
cout<<*(array+i)<< " ";
}
Both cout statements will print same only.
in short
array[i] compiler will internally convert into *(array+i) like this only
in the second cout statement from base address of an array it won't add value,since it is an pointer it will add sizeof(int) each time for an increment

How to read in a matrix from a file in C++?

I am attempting to read in an n × n matrix from a file and then store that matrix in a one dimensional array. I would also like to store the value for n. I have looked into various approaches but can't seem to apply them to what I'm trying to achieve.
This is what I have so far but I'm unsure what to put into the while loop.
/*READ IN THE IMAGE MATRIX FROM THE FILE*/
String lineA;
ifstream imFile;
imFile.open("imageMatrixDefined.txt");
if(imFile.fail()){
cerr << "File cannot be found or opened" << endl;
exit(1);
}
if(imFile.is_open(){
cout << "file opened successfully!" << endl;
while(!imFile.eof()){
}
}
The input file could look like the following:
1 2 3
2 3 1
3 3 2
where a tab separates the elements.
Any suggestions would be greatly appreciated as I'm new to C++.
Arrays have a fixed size.
You have to get the value for n first before initializing an array.
It's good to double check if you would like to store that matrix in a one dimensional array or a two dimensional array. If it is a one dimensional array, checking how the matrix is stored in a one dimensional array is good. Some stores it first row, second row, ..., and nth row, and some stores it first column, second column, ..., and nth column.
The matrix is n × n, so the number of columns is equal to the number of rows.
The file stores one row at a time.
Getting the value of n is not difficult.
The while loop is critical, but before the while loop, getting the value of n is the first step of solving the problem.
When the value of n is gotten, the array is easy to be initialized.
You can read the line one by one from the file in the while loop, get each matrix element by using the delimiter as a tab character, and store the matrix element in the array.
Reading a 2D array to a file. Input is assumed to be comma separated, one row per line and x amount of columns per row, each column separated by a tab (\t) character. No EOL (end of line) tab's required, just a newline (\n). Remember to set rows and columns variables correctly. Code is tested to work correctly.
using namespace std;
#include <iostream>
#include <fstream>
int main() {
int rows=10, columns=10;
ifstream f("input.txt");
int input[rows][columns];
for (int i=0; i<rows; i++){
for (int j=0; j<columns; j++){
f >> input[i][j];
}
}
f.close();
// Here you can add processing of the file, for example, print it:
cout << "Input:" << endl;
for (int i=0; i<rows; i++){
for (int j=0; j<columns; j++){
cout << input[i][j] << " ";
}
cout << endl;
}
return 0;
}
You have to bind a custom input stream with your input file. Say your input file is "in.txt", and it looks the same as you have specified.
The following code then reads from the file, stores it in a 1D array and prints the resulting matrix in matrix form:
#include <iostream>
#include <fstream>
using namespace std;
int main () {
ifstream myfile;
myfile.open ("in.txt");
cout << "Reading from a file.\n";
int arr[10];
int k = 0;
for (int i = 0; i < 3; ++i)
{
for (int j = 0; j < 3; ++j)
{
myfile >> arr[k]; //Read it in a 1D array
cout << arr[k] << " ";
++k;
}
cout << "\n";
}
myfile.close();
return 0;
}
Output:
Reading from a file.
1 2 3
2 3 1
3 3 2

Output from array is wrong

#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <fstream>
using namespace std;
void make_array(ifstream &num, int (&array)[50]);
int main(){
ifstream file; // variable controlling the file
char filename[100]; /// to handle calling the file name;
int array[50];
cout << "Please enter the name of the file you wish to process:";
cin >> filename;
cout << "\n";
file.open(filename);
if(file.fail()){
cout << "The file failed to open.\n";
exit(1);
}
else{
cout << "File Opened Successfully.\n";
}
make_array(file, array);
file.close();
return(0);
}
void make_array(ifstream &num, int (&array)[50]){
int i = 0; // counter variable
while(!num.eof() && i < 50){
num >> array[i];
i = i + 1;
}
for(i; i>=0; i--){
cout << array[i] << "\n";
}
}
Alright, so this it my code so far. When I output the contents of the array, I get two really large negative numbers before the expected output. For example, if the file had 1 2 3 4 in it, my program is outputting -6438230 -293948 1 2 3 4.
Can somebody please tell me why I am getting these ridiculous values?
Your code outputs the array backwards, and also it increments i twice after it has finished reading all the values. This is why you see two garbage values at the start. I suspect you are misreporting your output and you actually saw -6438230 -293948 4 3 2 1.
You end up with the extra increments because your use of eof() is wrong. This is an amazingly common error for some reason. See here for further info. Write your loop like this instead:
while ( i < 50 && num >> array[i] )
++i;
Now i holds the number of valid items in the list. Assuming you do actually want to output them backwards:
while ( i-- > 0 )
cout << array[i] << "\n";
To output them forwards you'll need two variables (one to store the total number of items in the array, and one to do the iteration)
The check !num.eof() only tells you that the last thing you read was not eof. So, if your file was 1 2 3 4, the check will only kick in after the 5th num>>array[i] call. However, for that i, array[i] will be populated with a meaningless value. The only correct way to deal with eofs is to check for validity on every call to operator>>. In other words, the right condition is simply num>>array[i]. This works by exploiting this conversion to bool since C++11 and to void* pre-C++11.

How do I fill an array with characters from user input, while counting how many array indexes have been used? (using cin.get)

I need to use the get function and count how many indexes have been filled I have been running into a couple problems.
It seems that using cin.get in this way only allows me to fill the array and doesn't allow me to count how many variables in the array have been filled:
#include <iostream>
int main()
{
char line[25];
cout << " Type a line terminated by enter\n>";
cin.get( line, 25 );
}
I have a feeling that I need to use a for loop such as the one below, but the problem with this is it doe not end with enter, the user has to fill the whole array and I need to be able to enter any amount of characters under the limit. Also the example did not use sentinel value, so though it would seem to solve this, it doesn't seem to be the solution.
void fill_array(char array[], int max_count, int& num_used)
{
char input;
int index = 0;
cout << "Enter a text string to test" << endl;
for( index = 0;index < max_count; index++)
{
cin.get(input);
array[index] = input;
num_used++;
}
}
You can use gcount to get the number of characters read byt the last unformatted operation, like cin.get.
char line[25];
cout << " Type a line terminated by enter\n>";
cin.get( line, 25 );
std::streamsize read_chars = cin.gcount();