C++ one dimensional Char array saving to two dimensional Char array - c++

char binarycode[5][5];
string tmp;
cout<<"Please type first 5 binary numbers: ";
cin>>tmp;
char tmp2[5];
strcpy(tmp2, tmp.c_str());
binarycode[0] = tmp2;
This is my code for me to save the empty char array with user input string. So there will be 5 string that will break up to one dimension char array and will be saved to each row of binarycode. Howerver, it does not seems to work like Java where i can just store the one dimension array to two dimension array. Are there any way to make this process easier or is making method is better?

Are there any way to make this process easier or is making method is
better?
Consider using std::vector of std::string like std::vector < std::string > binarycode ;
Then,
binarycode.reserve( 5 );
std::string tmp;
for ( int i = 1; i <=5; ++i )
{
std::cin >> tmp;
binarycode.push_back ( tmp );
}

Your objective is to take a 1 dimensional array with size T and to populate or convert it to a 2 dimensional array with size MxN. What you will need to do in order to construct this algorithm before writing any code implementation is you will need to know before hand the sizes or lengths of both M and N and in your case you have explicitly expressed that it will be a 5x5 in size; T shouldn't matter in this case. M will be the size of your rows, where N will be the size of your columns. To do this you will need to traverse the single array for its size and then depending on its indexed value it should correspond to a (m,n) value. Another words you need to map A(n) to B(m,n).
The method that you are trying to achieve which is not the simplest or even the most efficient but mimics the algorithm mathematically would be as follows:
#include <iostream>
#include <string>
int main() {
char binaryCode[5][5] { 0 }; // Initialize to all 0s
char temp;
int row = 0;
int col = 0;
do {
std::cout << "Enter 5 binary number: ";
std::cin >> temp;
for ( ; col < 5; col++ ) {
binaryCode[row][col] = temp[col];
}
col = 0;
temp.clear();
row++;
} while( row < 5 );
row = 0;
col = 0;
std::cout << "\nResults:\n";
for ( ; row < 5; row++ ) {
for ( ; col < 5; col++ ) {
std::cout << binaryCode[row][col] << " ";
}
std::cout << "\n";
col = 0;
}
return 0;
}
However this first approach is a little naïve and as P0W already stated with his answer:
#include <iostream>
#include <string>
#include <vector>
int main() {
std::vector<std::string> binaryCodes;
binaryCodes.reserve( 5 );
std::string tmp;
for ( int i = 1; i <=5; ++i ) {
std::cin >> tmp;
binarycode.push_back ( tmp );
}
return 0;
}
Is cleaner and simpler and does exactly the same thing that you would need.

The strcpy(0 function copies entire c-string to memory position you designated as destination. In code
char tmp2[5];
strcpy(tmp2, tmp.c_str());
In code
binarycode[0] = tmp2;
you attempted to save pointer - address of that buffer to a byte.
you statically allocated 5 bytes(!) of memory, then attempted to copy string to that memory. If anything, you would cause memory corruption this way, because rest of string would go somewhere.
C++ is not Java and you should thoroughly read books on this language, about syntax and standard you're using, not relying on something that "looks like". There are even principal differences between C and C++ in some areas.
If anything, iostreams provide all tools you need to get values from user input, but "proper" way to do requires handling cases of incorrect input. Consider this function:
#include <limits>
#include <iostream>
char getChar()
{
while (1) // Loop until user enters a valid input
{
std::cout << "Enter a byte value: ";
int x; // if we'll use char, cin would assume it is a character
std::cin >> x;
if (std::cin.fail()) // has a previous extraction failed?
{
// let's handle the failure
// or next >> will try parse same input
std::cout << "Invalid input from user.\n";
std::cin.clear(); // put us back in 'normal' operation mode
std::cin.ignore(std::numeric_limits<std::streamsize>::max(),'\n');
// and remove the bad input
}
//else if ( ((char)(x & 0xff)) != x ){
else if(( x > std::numeric_limits<char>::max()) ||
( x < std::numeric_limits<char>::min()))
{
// char can be from -127 to 127, it's one byte..
// int is allowing large values
std::cout << "Invalid value.\n";
}
else // nope, so return our good x
return (char)(x & 0xff);
}
}
The char is a pain in the backside with std::iostream, it always should be an int instead. Casting to smaller variable, like (char)x might be an undefined behavior, so need to mask larger values (char)(x & 0xff); For other types this function can become a template based on the type requested.
Now we should make it understand binary input? there is no predefined manipulator for binary format, you must input a string, validate it, and convert yourself.
int binaryToDec(std::string number)
{
int result = 0, pow = 1;
for ( int i = number.length() - 1; i >= 0; --i, pow <<= 1 )
result += (number[i] - '0') * pow;
return result;
}
std::string validateEntry()
{
bool valid = true;
std::string tempStr;
do
{
valid = true;
getline(std::cin, tempStr);
for (int i = 0; i < tempStr.length(); i++)
{
if ((tempStr.compare(i, 1, "0") != 0) && (tempStr.compare(i, 1, "1") != 0))
{
valid = false;
std::cout << "Enter Valid Binary Number: ";
break;
}
}
} while (valid == false);
return tempStr;
}
Use those in pattern:
std::cout << "Enter Binary Number: ";
std::string binaryString = validateEntry();
int binaryNum = binaryToDec(binaryString);

Related

Creating strings by splitting a char array

As part of my homework assignment, I have to split a char[] by its indices. So for example, the main function looks like:
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size;
cout << "Enter the size of the part: ";
cin >> split_size;
int size = sizeof(str) / sizeof(str[0]);
SplitString(str, split_size, size);
int wait;
cin >> wait;
return 0;
}
Then using the function SplitString, the first x elements are printed, new line, then the next.
My first idea, was to use two for loops. One loops through the splits (i.e. if there are 4 splits, the range on this loop is 0 to 3), then the second loops through the split itself, iterating over the array elements.
My SplitString() function looks like this:
void SplitString(char str[], int split_size, int size) {
int parts = size / split_size;
for (int i = 0; i < parts; i++) {
for (int j = 0; j < split_size; j++) {
j = split_size * i;
cout << str[j];
}
cout << endl;
}
}
Is there an easier way to do this? I know in Python, you can use the arr[1:] to grab a range of elements from the array. Is there anything similar in C++? Is there some flaw in my logic? Is there something wrong with my code?
cout comes with a write function that takes a pointer and a size argument.
for (int i = 0; i < parts; i++) {
cout.write (str+i*split_size, split_size)
cout << endl;
}
Note that the code above does not check if the string is actually long enough. If the total size is not equal the split_size times a whole number, you will have to add an additional check.
Also, note that this:
int size = sizeof(str) / sizeof(str[0]);
can be written as:
int size = sizeof(str);
instead because the size of a char is always 1.
You can use std::string for this. Alternatively, if your compiler supports C++17, you can use std::string_view as the first argument of SplitString to avoid unnecessary copying.
#include <algorithm>
#include <iostream>
#include <string>
void SplitString(std::string s, std::size_t split_size)
{
while(!s.empty())
{
auto size = std::min(split_size, s.size());
std::cout << s.substr(0, size) << '\n';
s = s.substr(size, std::string::npos);
}
}
int main()
{
char str[] = "A string to be split into given number of parts";
int split_size = 5;
SplitString(str, split_size);
return 0;
}
Live example.

How do I fit in a comma separated number matrix into a dynamically allocated array in C++?

I have a file that stores a number matrix of unknown shape in format like
-1,4,12,5.7
2.1,3,-10,3.3
7.1,1.11,12,10
I attempt to store the matrix in a dynamically allocated array because I cannot hard code the number of row and column. For this part, I used pointer-to-pointer and a demo is as below,
#include <iostream>
using namespace std;
int main()
{
// Rather than user input, I need to change this part to deciding the shape of the matrix myself
int row, col;
cout << "Enter row number and column number, separated with a space:\n";
cin >> row >> col;
int** p_p_grid = new int* [row];
for(int i = 0; i < row; i++)
{
p_p_grid[i] = new int[col];
}
// Fill in the entries
for(int i = 0; i < row; i++)
{
for(int j = 0; j < col; j++)
{
// (i + 1) * (j + 1) needs to be replaced by true entries in the matrix
p_p_grid[i][j] = (i + 1) * (j + 1);
}
}
return 0;
}
But what is an efficient way to decide the shape of a comma separated number block before assigning the number one by one? And also how do I import a CSV-structured matrix in C++? (For some reason, I don't want to use a vector type, so please focus on an array)
what is an efficient way to decide the shape of a comma separated
number block before assigning the number one by one?
Assuming you're reading from a file stream, the easiest way, would be to read the file twice: one for counting rows and commas, on for doing the real input.
Here an example of how to detect the end of the matrix, stoping when the number of elements of a new line don't match the format of the matrix:
int nrows=1, ncols=0;
string line;
while (getline(ifs, line)) {
int n=1;
for (auto x: line) // count commas in the line
if (x==',')
n++;
if (!ncols)
ncols = n; // first line sets th enumber of columns
else if (n == ncols) // subsequent lines increase the row count
nrows++;
else break; // unless the format does'n match anymore
}
ifs.clear(); // remove eof
ifs.seekg (0, ifs.beg); // rewind
Online demo
What causes lack of efficiency in this approach, is that you read the file twice. For this reason, by the way, you can't use this approach for reading cin: you can't rewind.
You can optimize this either by caching the lines read (but you'd need to manage a rowing array of strings, as you're not allowed to use vectors), or by letting the matrix grow dynamically (which no longer correspond to your question as this would not provide the matrix size upfront).
how do I import a CSV-structured matrix in C++
Within each line, just read the doubles, followed by a char (which should be the ','):
char forget_me;
for (int i=0; i<nrows; i++)
for (int j=0; j<ncols; j++) {
cin >> p_p_grid[i][j];
if (j<ncols-1)
cin>>forget_me;
}
I know you didn't want a vector-based solution, but here's one anyway
int main() {
ifstream input("input.txt");
if(!input) {
cerr << "couldn't open file" << endl;
exit(1);
}
double number;
vector<vector<double>> matrix;
vector<double> current_row;
while(input >> number) { // loop once for each number in the file
current_row.push_back(number);
int next_char = input.get(); // should be ',' or '\n'
if(next_char == '\n') {
// current row is finished
matrix.push_back(current_row);
current_row.clear();
}
}
// now print the matrix back out again
for(auto const & one_row : matrix) {
for(auto one_number : one_row) {
cout << "\t," << one_number;
}
cout << endl;
}
}
It a bit fiddly. Use either C++ iostream or C stdio.h, and read in a whole line. So if using getline / fgets, you need a very big buffer, say 8k. Now for the first line, parse into fields. For a first attempt, simply count the commas, but the actual rules are more complicated than that.
The go through line by line, extracting the data. Since you've no say over the number of rows, you've no choice other than to dynamically grow the buffer for each line. An STL vector makes this easy for you - just push it back and the buffer will grow. However if you want you can use this structure
int **p_p_grid = 0;
int Nrows = 0;
int Ncolumns = 0;
/* ( for first line, fill the number of columns) */
/* for each line */
p_p_grid = realloc((Nrows + 1) * sizeof(int *));
if(!p_p_grid)
memory_failure();
p_p_grid[Nrows] = malloc(Ncolums * sizeof(int));
if(!p_p_grid[Nrows])
memory_failure();
for(i=0;i<Ncolumns;i++)
p_p_grid[Nrows][i] = /* parse logic here */
Nrows++;
As noted, I would use std::vector instead. Considering that each row have a fixed number of elements, I would also be using std::array. Perhaps doing something like this:
#include <vector> // For std::vector
#include <array> // For std::array
#include <string> // For std::string and std::getline
#include <fstream> // For std::ifstream
#include <sstream> // For std::isstream
int main()
{
std::vector<std::array<double, 4>> grid;
std::ifstream input{"input.txt"};
std::string line;
// Outer loop reads the rows
while(std::getline(input, line))
{
int i = 0;
std::istringstream iss{line};
std::array<double, 4> values;
double value;
// Inner loop extracts the values on each row
while (iss >> value)
{
values[i] = value;
// Skip over the comma
iss.ignore(std::numeric_limits<std::streamsize>::max(), ',');
}
grid.push_back(values);
}
// Now print the values
int row_number = 1;
for (auto const& row : grid)
{
std::cout << "Row " << row_number++ << ": ";
for (auto const value : row)
{
std::cout << value << ' ';
}
std::cout << '\n';
}
}
Note that I haven't actually tested the code above. It compiles cleanly though.

Algorithm to print asterisks for duplicate characters [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I was asked this question in an interview:
Given an array with the input string, display the output as shown below
Input
INDIA
Output
INDA
****
*
I iterated through the array and stored each character as a key in std::map with value as number of occurrence. Later I iterate the map and print the asteriks and reduce the value in the map for each character.
Initially, I was asked not to use any library. I gave a solution which needed lot of iterations. For every character, iterate the complete array till the index to find previous occurrences and so on.
Is there any better way, e.g. better complexity, such as faster operation, by which this can be achieved?
Essentially what you are asking is how to implement map without using the STL code, as using some kind of data structure which replicates the basic functionality of map is pretty much the most reasonable way of solving this problem.
There are a number of ways of doing this. If your keys (here the possible characters) come from a very large set where most elements of the set don't appear (such as the full Unicode character set), you would probably want to use either a tree or a hash table. Both of these data structures are very important with lots of variations and different ways of implementing them. There is lots of information and example code about the two structures around.
As #PeterG said in a comment, if the only characters you are going to see are from a set of 256 8-bit chars (eg ASCII or similar), or some other limited collection like the upper-case alphabet you should just use an array of 256 ints and store a count for each char in that.
here is another one:
You can see it working HERE
#include <stdio.h>
int main()
{
int i,j=0,f=1;
char input[50]={'I','N','D','I','A','N','A','N'};
char letters[256]={0};
int counter[256]={0};
for(i=0;i<50;i++)
{
if(input[i])
counter[input[i]]++;
if(counter[input[i]]==1)
{
putchar(input[i]);
letters[j]=input[i];
j++;
}
}
putchar('\n');
while(f)
{
f=0;
for(i=0;i<j;i++)
if(counter[letters[i]])
{
putchar('*');
counter[letters[i]]--;
f=1;
}
else
{
putchar(' ');
}
putchar('\n');
}
return 0;
}
If the alphabet under consideration is fixed, it can be done in two passes:
Create an integer array A with the size of the alphabet, initialized with all zeros.
Create a boolean array B with size of the input, initialize with all false.
Iterate the input; increase for every character the corresponding content of A.
Iterate the input; output a character if its value it B is false and set its value in B to true. Finally, output a carriage return.
Reset B.
Iterate input as in 4., but print a star if if the character's count in A is positive, then decrease this count; print a space otherwise.
Output a carriage return; loop to 5 as long as there are any stars in the output generated.
This is interesting. You shouldnt use a stl::map because that is not a hashmap. An stl map is a binary tree. An unordered_map is actually a hash map. In this case we dont need either. We can use a simple array for char counts.
void printAstr(std::string str){
int array[256] ;// assumining it is an ascii string
memset(array, 0, sizeof(array));
int astrCount = 0;
for(int i = 0; i < str.length()-1; i++){
array[(int) str[i]]++;
if(array[(int) str[i]] > 1) astrCount++;
}
std::cout << str << std::endl;
for(int i = 0; i < str.length()-1;i++) std::cout << "* ";
std::cout << std::endl;
while(astrCount != 0){
for(int i= 0; i< str.length() - 1;i++){
if(array[(int) str[i]] > 1){
std::cout << "* ";
array[(int) str[i]]--;
astrCount--;
}else{
std::cout << " ";
}
}
std::cout << std::endl;
}
}
pretty simple just add all values to the array, then print them out the number of times you seem them.
EDIT: sorry just made some logic changes. This works now.
The following code works correctly. I am assuming that you can't use std::string and take note that this doesn't take overflowing into account since I didn't use dynamic containers. This also assumes that the characters can be represented with a char.
#include <iostream>
int main()
{
char input[100];
unsigned int input_length = 0;
char letters[100];
unsigned int num_of_letters = 0;
std::cin >> input;
while (input[input_length] != '\0')
{
input_length += 1;
}
//This array acts like a hash map.
unsigned int occurrences[256] = {0};
unsigned int max_occurrences = 1;
for (int i = 0; i < input_length; ++i)
{
if ((occurrences[static_cast<unsigned char>(input[i])] += 1) == 1)
{
std::cout<< " " << (letters[num_of_letters] = input[i]) << " ";
num_of_letters += 1;
}
if (occurrences[static_cast<unsigned char>(input[i])] > max_occurrences)
{
max_occurrences = occurrences[static_cast<unsigned char>(input[i])];
}
}
std::cout << std::endl;
for (int row = 1; row <= max_occurrences; ++row)
{
for (int i = 0; i < num_of_letters; ++i)
{
if (occurrences[static_cast<unsigned char>(letters[i])] >= row)
{
std::cout << " * ";
}
else
{
std::cout << " ";
}
}
std::cout << std::endl;
}
return 0;
}
The question is marked as c++ but It seems to me that the answers not are all quite C++'ish, but could be quite difficult to achieve a good C++ code with a weird requirement like "not to use any library". In my approach I've used some cool C++11 features like in-class initialization or nullptr, here is the live demo and below the code:
struct letter_count
{
char letter = '\0';
int count = 0;
};
int add(letter_count *begin, letter_count *end, char letter)
{
while (begin != end)
{
if (begin->letter == letter)
{
return ++begin->count;
}
else if (begin->letter == '\0')
{
std::cout << letter; // Print the first appearance of each char
++begin->letter = letter;
return ++begin->count;
}
++begin;
}
return 0;
}
int max (int a, int b)
{
return a > b ? a : b;
}
letter_count *buffer = nullptr;
auto testString = "supergalifragilisticoespialidoso";
int len = 0, index = 0, greater = 0;
while (testString[index++])
++len;
buffer = new letter_count[len];
for (index = 0; index < len; ++index)
greater = max(add(buffer, buffer + len, testString[index]), greater);
std::cout << '\n';
for (int count = 0; count < greater; ++count)
{
for (index = 0; buffer[index].letter && index < len; ++index)
std::cout << (count < buffer[index].count ? '*' : ' ');
std::cout << '\n';
}
delete [] buffer;
Since "no libraries are allowed" (except for <iostream>?) I've avoided the use of std::pair<char, int> (which could have been the letter_count struct) and we have to code many utilities (such as max and strlen); the output of the program avobe is:
supergaliftcod
**************
* ******* *
* *** *
* *
*
*
My general solution would be to traverse the word and replace repeated characters with an unused nonsense character. A simple example is below, where I used an exclamation point (!) for the nonsense character (the input could be more robust, some character that is not easily typed, disallowing the nonsense character in the answer, error checking, etc). After traversal, the final step would be removing the nonsense character. The problem is keeping track of the asterisks while retaining the original positions they imply. For that I used a temp string to save the letters and a process string to create the final output string and the asterisks.
#include <iostream>
#include <string>
using namespace std;
int
main ()
{
string input = "";
string tempstring = "";
string process = "";
string output = "";
bool test = false;
cout << "Enter your word below: " << endl;
cin >> input;
for (unsigned int i = 0; i < input.length (); i++)
{ //for the traversed letter, traverse through subsequent letters
for (unsigned int z = i + 1; z < input.length (); z++)
{
//avoid analyzing nonsense characters
if (input[i] != '!')
{
if (input[i] == input[z])
{ //matched letter; replace with nonsense character
input[z] = '!';
test = true; //for string management later
}
}
}
if (test)
{
tempstring += input[i];
input[i] = '*';
test = false; //reset bool for subsequent loops
}
}
//remove garbage symbols and save to a processing string
for (unsigned int i = 0; i < input.size (); i++)
if (input[i] != '!')
process += input[i];
//create the modified output string
unsigned int temp = 0;
for (unsigned int i = 0; i < process.size (); i++)
if (process[i] == '*')
{ //replace asterisks with letters stored in tempstring
output += tempstring[temp];
temp++;
}
else
output += process[i];
//output word with no repeated letters
cout << output << endl;
//output asterisks equal to output.length
for (unsigned int a = 0; a < output.length (); a++)
cout << "*";
cout << endl;
//output asterisks for the letter instances removed
for (unsigned int i = 0; i < process.size (); i++)
if (process[i] != '*')
process[i] = ' ';
cout << process << endl << endl;
}
Sample output I received by running the code:
Enter your word below:
INDIA
INDA
****
*
Enter your word below:
abcdefgabchijklmnop
abcdefghijklmnop
****************
***
It is possible just using simple array to keep count of values.
#include<iostream>
#include<string>
using namespace std;
int main(){
string s;
char arr[10000];
cin>>s;
int count1[256]={0},count2[256]={0};
for(int i=0;i<s.size();++i){
count1[s[i]]++;
count2[s[i]]++;
}
long max=-1;
int j=0;
for(int i=0;i<s.size();++i){
if(count1[s[i]]==count2[s[i]]){ //check if not printing duplicate
cout<<s[i];
arr[j++]=s[i];
}
if(count2[s[i]]>max)
max=count2[s[i]];
--count1[s[i]];
}
cout<<endl;
for(int i =1; i<=max;++i){
for(int k=0;k<j;++k){
if(count2[arr[k]]){
cout<<"*";
count2[arr[k]]--;
}
else
cout<<" ";
}
cout<<endl;
}
}

Error-correcting loop in C++, find specific chars in a string and flag as bad input

Here is v1.0 of the binary_to_decimal converter I wrote. I want to make several changes as I keep improving the spec. Classes and pointers will be added as well in the future. Just to keep me fresh and well practiced.
Well, I now want to implement an error-correcting loop that will flag any character that is not a 0 or a 1 and ask for input again.
I have been trying something along the line of this code block that worked with an array.
It might be way off but I think I can tweak it. I am still learning 0_0
I want to add something like this:
while ((cin >> strint).get())
{
cin.clear(); //reset the input
while (cin.get() != '\n') //clear all the way to the newline char
continue; //
cout << "Enter zeroes and/or ones only! \n";
}
Here is the final code without the error-correcting loop:
#include <iostream>
#include <cmath>
#include <string>
using namespace std;
const int MAX = 100;
int conv(int z[MAX], int l[MAX], int a);
int main()
{
int zelda[MAX];
int link[MAX];
string strint;
int am;
cout << "Enter a binary number: \n";
(cin >> strint).get(); //add error-correction to only read 0s and 1s.
am = strint.size();
cout << am << " digits entered." << endl;
int i = 0;
int p = 0;
while (i < am)
{
zelda[i] = strint[p] - '0'; //copies the string array elements into the int array; essentially STRING TO INT (the minus FORCES a conversion because it is arithmetic) <---- EXTREMELY CLEVER!
++i;
++p;
}
cout << conv(zelda, link, am);
cin.get();
return 0;
}
int conv(int zelda[MAX], int link[MAX], int length)
{
int sum = 0;
for (int t = 0; t < length; t++)
{
long int h, i;
for (int h = length - 1, i = 0; h >= 0; --h, ++i)
if (zelda[t] == 1)
link[h] = pow(2.0, i);
else
link[h] = 0;
sum += link[t];
}
return sum;
}
thanks guys.
I'm not completely sure of what you're trying to do, but I think what you're wanting is string::find_first_not_of. There's an example included in that link. You could have something like: myString.find_first_not_of("01");
If the return value is string::npos, then there are no characters in the string other than 1 or 0, therefore it's valid. If the return value is anything else, then prompt again for valid input and continue looping until the input's valid.

How to read an unknown contents of a text file into a 2d array

I am trying to read the unknown contents of a text file into a 2D array and have it come out looking like:
M [0] [0]=2 M [0] [1]=1 M [0] [2]=0
M [1] [0]=0 M [1] [1]=1 M [1] [2]=3
M [2] [0]=8 M [2] [1]=9 M [2] [2]=1
M [3] [0]=3 M [3] [1]=5 M [3] [2]=2
when the text file looks like this:
2
1 0
0 1
3
8 9 1
3 5 2
-2 3 -1
0
The zero at the end shows the end of the file.
My problem is the array can be a max size of 10X10 so there is no way of knowing what the size of the 2D array is and how to get it to look like i have shown above.
Any ideas?
Just use 'fstream'. It ignores new lines and works just like 'iostream'. You just need to keep track of your matrix row and column.
//open "myFileName.txt" with an input file stream
std::ifstream inputFile("myFileName.txt");
while(!inputFile.eof()) //Check for end-of-file character
{
//do this while keeping track of your matrix position
inputFile >> M [curRow] [curColumn]
}
inputFile.close();
And don't forget to include the library:
#include <fstream>
Edit: The >> operator will also attempt to auto-cast the input as whatever type you are using:
double dTemp;
int iTemp;
std::string sTemp;
std::ifstream in("myFile.txt");
in >> dTemp; //input cast as double
in >> iTemp; //input cast as integer
in >> sTemp; //input cast as string
in.close();
Edit: Get the number of elements of the file
int temp, numberOfInputs;
while(!inputFile.eof())
{
inputFile >> temp;
++numberOfInputs;
}
inputFile.seekg(0, std::ios::beg); //Go to beginning of file
Once you have the number of inputs you can use that to figure out the number of rows and colums.
For some dimensions N x M
char c;
int x;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
c = fgetc(file);
if(c == ' ') continue;
if(c == EOF) return;
if(c == '-')
{
c = fgetc(file);
x = -1 * ((int)c);
} else {
x = c;
}
if(x == 0)
{
array[i][j] = x;
} else {
return;
}
}
}
But if you're talking about "what's the size of the matrix required to store these" then you're going to need a way to figure out what dimensions you want.
Try:
#include <vector>
#include <fstream>
#include <iostream>
int main()
{
std::ifstream file("plop.dat");
if(!file)
{
std::cerr << "Failed to open File\n";
return 1;
}
// Keep looping until we are done.
while(true)
{
int size;
file >> size;
// You said a size zero indicates termination.
if (size == 0)
{ break;
}
// Create a square 2D vector (Vector inside a Vector)
std::vector<std::vector<int> > matrix(size, std::vector<int>(size, 0));
// Loop over each axis
for(int x = 0;x < size; ++x)
{
for(int y = 0;y < size; ++y)
{
// Read one number for each location.
// The operator >> automatically skips white space
// White Space includes newline and tab. So it should work
// perfectly if the input is OK. But it is hard to detect
// an error in the format of the file.
file >> matrix[x][y];
}
}
}
}
~
So all row of the array have 3 values?
Simply read the values into the array keeping a count of which column you are in and ignore the newlines?
Look at getline
getline and stringstream to read, vector< vector<int> > to store.
Edit: Oh, so the size is always N*N? Then just read using while(cin>>x) { if (cin.good()) ...; } into a vector<int>, check the total size, and split into vector< vector<int> >
Single and multi-dimensional C arrays are just contiguous pieces of memory. The difference is more syntactical in terms of what indexing into the array does: for a 2-dimensional array it just multiplies one dimension by the size of the other dimension before adding the second dimension to find the offset.
So to solve:
read the values into a std::vector (other answers have sugegsted ways to do this)
work out the size (integer square root of myArray.size())
calculate the index as, e.g.:
int idx(int size, int d1, int d2)
{
return (d1*size)+d2;
}
Return the vector element at the index e.g.:
for (int d1 = 0; d1 < size; d1++)
{
for (int d2 = 0; d2 < size; d2++)
std::cout << "M [" << d1 << "] [" << d2 << "]=" << myArray[idx(size, d1, d2)] << " ";
std::cout << std::endl;
}
gives me:
$ g++ arr.cpp && ./a.out
M[0][0]=2 M[0][1]=1 M[0][2]=0
M[1][0]=0 M[1][1]=1 M[1][2]=3
M[2][0]=8 M[2][1]=9 M[2][2]=1