Problems reading data into array

Assignment trouble
The txt

1
2
3
4
5
94 49 96 67 82 34 91 64 15 97 98 78 Hong Kong
71 57 17 31 63 38 77 74 61 22 27 59 New York
36 16 30 19 29 41 23 25 22 37 28 29 Beverly Hills
87 48 49 91 72 69 13 97 43 41 29 58 Rio De Janeiro 
34 32 74 57 32 80 76 40 64 48 41 68 Los Angeles



My code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
void readFile(string);
int main()
{
	string filename;
	
	cout<<"Please enter the name of txt : ";
	getline(cin,filename);
	
	readFile(filename);
	
	return 0;
}

void readFile(string filename)
{
	
	const int row=5;
	const int col=12;
	int sales[row][col];
	int counter=0;
	ifstream indata;
	indata.open(filename.c_str());
	string town[counter];
	int num1, num2, num3, num4, num5, num6, num7, num8, num9, num10, num11, num12;
	
	for(int i=0; i<row; i++) //READ SALES DATA INTO ARRAYS
	{
		for(int j=0; j<col; j++)
		{
			indata>>sales[i][j];
		}
	}
	
	while(getline(indata, town, ' '))
	{
		indata>>num1; indata.ignore();
		indata>>num2; indata.ignore();
		indata>>num3; indata.ignore();
		indata>>num4; indata.ignore();
		indata>>num5; indata.ignore();
		indata>>num6; indata.ignore();
		indata>>num7; indata.ignore();
		indata>>num8; indata.ignore();
		indata>>num9; indata.ignore();
		indata>>num10; indata.ignore();
		indata>>num11; indata.ignore();
		indata>>num12; indata.ignore();
		
		indata>>town[counter];
		counter++;
	}

	cout<<town[0];

}


I want to put the numbers into a 2 dimensional array while put the cities into single dimensional array. After successfully done the 2d array, I can't find a way to do the cities array. I was told to use while(getline()) but I know this is not the right way. Can somebody correct me? I am new to C++, I haven't learn to use vectors. Any help will be appreciated.
Maybe like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
void readFile(string filename)
{
  const int row = 5;
  const int col = 12;
  int sales[row][col];
  
  ifstream indata;
  indata.open(filename.c_str());
  if (!indata)
  {
    cerr << "Error opening file....";
    return;
  }
  string town[row];
  
  int j;
  for (int i = 0; i<row; i++) //READ SALES DATA INTO ARRAYS
  {
    for (j = 0; j<col; j++)
    {
      indata >> sales[i][j];
    }
    if (indata)
      getline(indata, town[i]);
  }

  // output data to see if we read it correctly

  cout << "Data read:\n";
  cout << "----------\n\n";

  for (int i = 0; i<row; i++)
  {
    for (j = 0; j<col; j++)
    {
      cout << sales[i][j] << " ";
    }
    cout << town[i] << "\n";
  }
  
}


Data read:
----------
94 49 96 67 82 34 91 64 15 97 98 78  Hong Kong
71 57 17 31 63 38 77 74 61 22 27 59  New York
36 16 30 19 29 41 23 25 22 37 28 29  Beverly Hills
87 48 49 91 72 69 13 97 43 41 29 58  Rio De Janeiro
34 32 74 57 32 80 76 40 64 48 41 68  Los Angeles
What if the cities name is on the first column?
Last edited on
What if the cities name is on the first column?

It depends on the file format. If it looks something like this:
Hong Kong, 94 49 96 67 82 34 91 64 15 97 98 78
New York, 71 57 17 31 63 38 77 74 61 22 27 59
Beverly Hills, 36 16 30 19 29 41 23 25 22 37 28 29
Rio De Janeiro, 87 48 49 91 72 69 13 97 43 41 29 58
Los Angeles, 34 32 74 57 32 80 76 40 64 48 41 68

then it isn't too hard, because the comma indicates where the name ends. You might then use getline with a comma delimiter:
 
    getline(fin, cities[i], ',')


But If there is no clear way to identify the end of the city name, it can sometimes be more tricky, because it might consist of just one word, or several words.
Last edited on
But If there is no clear way to identify the end of the city name, it can sometimes be more tricky, because it might consist of just one word, or several words.


Unfortunately, my assignment txt file doesn't have any comma. So, what can be done?


1
2
3
4
5
Hong Kong 94 49 96 67 82 34 91 64 15 97 98 78
New York 71 57 17 31 63 38 77 74 61 22 27 59
Beverly Hills 36 16 30 19 29 41 23 25 22 37 28 29
Rio De Janeiro 87 48 49 91 72 69 13 97 43 41 29 58
Los Angeles 34 32 74 57 32 80 76 40 64 48 41 68
Last edited on
Read the whole line into a string.
Use std::string.find_first_of() to find the first number.
Split into substrings at this point.
Take the first part, trim the blank(s) from its end, assign to city.
Stringstream the second part into the number variables.
Can you give me a example in the form of code?
Last edited on
But that would be doing your assignment!

If you choose to follow that route, then the tutorial and reference on this site actually give code samples for each step.
Though the method suggested by lastchance is a good one, and the way I would have suggested, there are alternatives.

What if for example the first part is an address which contains numbers? You don't want to misidentify a number within the address as a sales figure.

Read one line at a time, for example
Hong Kong 94 49 96 67 82 34 91 64 15 97 98 78

Then start from the end of the string, find the position of the last numeric character, in this example it would be the digit '8'. Starting from that position, find the position of the previous space. That takes you to the space between "98 78".

Now repeat that another eleven times, find a digit, find a space. After doing it 12 times, you will have the position of the space just before the first number. Now you can split the string (using substr() function), the first part is the name, the last part is the numbers.

After that, to get the numbers from the string, the easiest way is to use a stringstream.

references with examples:
http://www.cplusplus.com/reference/string/string/find_last_of/
http://www.cplusplus.com/reference/sstream/istringstream/istringstream/
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
#include <string>
#include <vector>
#include <sstream>

struct city_info
{
    std::string name ; // name of the city
    static constexpr std::size_t N = 12 ; // size of the array of numbers
    int numbers[N] {} ; // associated data (N numbers)
};

std::istream& get_city_info( std::istream& stm, city_info& info )
{
    // read in a complete line
    std::string line ;
    std::getline( stm, line ) ;

    // create an input string stream to read the tokens from the line
    std::istringstream str_stm(line) ;

    // read tokens one by one into a vector
    // https://cal-linux.com/tutorials/vectors.html
    std::vector<std::string> tokens ;
    std::string tok ;
    while( str_stm >> tok ) tokens.push_back(tok) ;

    if( tokens.size() > city_info::N ) // if we have sufficient number of tokens
    {
        const std::size_t offset_first_number = tokens.size() - city_info::N ;
        try
        {
            // extract the last N numbers into the array
            for( std::size_t i = 0 ; i < city_info::N ; ++i )
            {
                // try to convert each token to an int and add it to the vector
                // http://en.cppreference.com/w/cpp/string/basic_string/stol
                info.numbers[i] = std::stoi( tokens[ i + offset_first_number ] ) ;
            }

            // set the remaining tokens as the name of the city
            info.name = tokens.front() ;
            for( std::size_t i = 1 ; i < offset_first_number ; ++i )
                info.name += ' ' + tokens[i] ;

            return stm ; // if we reach here, the information has been extracted successfully
        }

        catch( const std::exception& ) {} // if we reach here, an error occurred during conversion
    }

    // http://en.cppreference.com/w/cpp/io/basic_ios/clear
    stm.clear( stm.failbit ) ; // signal input failure by putting the stream into a failed state
    info = {} ; // input failure: clear all fields in city_info
    return stm ;
}

int main()
{
    std::istringstream file( // test data (city names are deliberately mangled for testing)

        "1234 Hong Kong 94 49 96 67 82 34 91 64 15 97 98 78\n"
        "New 56 York 71 57 17 31 63 38 77 74 61 22 27 59\n"
        "Beverly -32 Hills 36 16 30 19 29 41 23 25 22 37 28 29\n"
        "Rio 123 De 456 Janeiro 87 48 49 91 72 69 13 97 43 41 29 58\n"
        "Los Angeles 999 34 32 74 57 32 80 76 40 64 48 41 68\n"
        "this line should fail 1 2 3 4 5 6 7 8 9 abc 11 12\n"
    );

    city_info info ;
    while( get_city_info( file, info ) ) // for each city_info that was read
    {
        // print it out
        std::cout << "name: " << info.name << "\nnumbers: " ;
        for( int v : info.numbers ) std::cout << v << ' ' ;
        std::cout << "\n\n" ;
    }
}

http://coliru.stacked-crooked.com/a/8551c5123e5f6c22
Topic archived. No new replies allowed.