Cannot convert '__gnu_cxx::_alloc_traits<std::allocator<std::_cxxll:basic_string<char>

Pages: 123
what does this error mean at line 96?

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
  // Program to read a CSV file containing company items into an array of structures
//
// Author: 
//
// date: 10/18/20
//
//


#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

#define DEBUG 1

#define MAX_ITEMS 4
struct Item {
    int partNumber;
    string partName;
    int partQuantity;
    double price;
};

bool openFileIn(fstream &, string);
int getItems(fstream &, Item *);
int showItems(Item *);
void split(const string&, char , vector<string>& );

int main()
{
	fstream dataFile;                   // data file
    Item *items = new Item[MAX_ITEMS];     // dynamically allocate student records

	if (openFileIn(dataFile, "widgets.dat"))
	{
        // get Student data from file into array
    	getItems(dataFile, items);

    	dataFile.close();

        showItems(items);
	}
	else
       cout << "File open error!" << endl;

	return 0;
}

//***********************************************************
// Definition of function openFileIn. Accepts a reference   *
// to an fstream object as an argument. The file is opened  *
// for input. The function returns true upon success, false *
// upon failure.                                            *
//***********************************************************

bool openFileIn(fstream &file, string name)
{
   file.open(name.c_str(), ios::in);
   if (file.fail())
      return false;
   else
      return true;
}


/*
 * getStudent data one line at a time from
 * the file. Parse the line using ',' as delimiter.
 * Save data read to a Item record pointed to
 * by s_ptr;
 */
int getItems(fstream &file, Item *s_ptr)
{
    string input;	// To hold file input
    int count = 0;

    // Read item data from file using ',' as a delimiter.
    while (count < MAX_ITEMS && getline(file, input)) {

        // vector to hold the tokens.
        vector<string> tokens;

        // Tokenize str1, using ' ' as the delimiter.
        split(input, ',', tokens);

        /*
         * copy the tokens to the item record
         */
        s_ptr->partNumber  = atoi(tokens.at(0).c_str());
        s_ptr->partName =  tokens.at(1);
        s_ptr->partQuantity =  tokens.at(2);
        s_ptr->price =  atof(tokens.at(3).c_str());

        count++;
        s_ptr++;
        cout << endl;
    }
}

/*
 * show all items
 */
int showItems(item *s_ptr)
{
    /* Display the headings for each column, with spacing and justification flags */
    printf("%-8s%-30s%-10s%-8s\n", "partNumber", "partName", "partQuantity", "price");

    // Read item data from file using ',' as a delimiter.
    for (int i = 0; i < MAX_ITEMS; i++) {

        if (s_ptr->partNumber != 0) {

            printf("%-8d%-30s%-10s%-2.2f\n",
                    s_ptr->partNumber,
                    s_ptr->partName.c_str(),
                    s_ptr->partQuantity.c_str(),
                    s_ptr->price);

            s_ptr++;
        }

        /* If the id field is zero, then we reached the last student, break
         * out of the for loop.
         */
        else
            break;
    }
}

//**************************************************************
// The split function splits s into tokens, using delim as the *
// delimiter. The tokens are added to the tokens vector.       *
//**************************************************************
void split(const string& s, char delim, vector<string>& tokens)
{
   int tokenStart = 0;  // Starting position of the next token

   // Find the first occurrence of the delimiter.
   int delimPosition = s.find(delim);

   // While we haven't run out of delimiters...
   while (delimPosition != string::npos)
   {
      // Extract the token.
      string tok = s.substr(tokenStart, delimPosition - tokenStart);

      // Push the token onto the tokens vector.
      tokens.push_back(tok);

      // Move delimPosition to the next character position.
      delimPosition++;

      // Move tokenStart to delmiPosition.
      tokenStart = delimPosition;

      // Find the next occurrence of the delimiter.
      delimPosition = s.find(delim, delimPosition);

      // If no more delimiters, extract the last token.
      if (delimPosition == string::npos)
      {
         // Extract the token.
         string tok = s.substr(tokenStart, delimPosition - tokenStart);

         // Push the token onto the vector.
         tokens.push_back(tok);
      }
   }
}
Copy'n'paste your code into Visual Studio 2019.....

Line 32, the function declaration int showItems(Item *);. Line 108 , the function definition int showItems(item *s_ptr). Item is not the same as item.

In your Item struct, line 25. partQuantity is declared as an int. Line 96 you are trying to assign a std::string to it.

Line 121 you are trying to get a c_str from an int.

Cryptic error message for an error from the C++ standard library about trying to ram a std::string into an int. It don't fit.
The FULL error message.
1
2
 In function 'int getItems(std::fstream&, Item*)':
96:29: error: cannot convert '__gnu_cxx::__alloc_traits<std::allocator<std::basic_string<char> > >::value_type {aka std::basic_string<char>}' to 'int' in assignment


Look at line 94, why did you call atoi() - what type is the structure member?
What does that tell you about line 96 and it's type?

So just declare partQuantity as a string then?
I'm still stuck on this, i understand i can't use an integer there but then what do i do alternately?
How come you figured out this.
s_ptr->partNumber = atoi(tokens.at(0).c_str());


But can't figure out this?
s_ptr->partQuantity = atoi(tokens.at(2).c_str());
Here some improvements, mostly for getting rid of the pointers and the plain record array. Also, I shrinked somewhat your spllit() function.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
  // Program to read a CSV file containing company items into an array of structures
//
// Author: 
//
// date: 10/18/20
//
//


#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstdlib>

using namespace std;

#define DEBUG 1

struct Item {
    int partNumber;
    string partName;
    int partQuantity;
    double price;
};

bool openFileIn(fstream &, string);
void getItems(fstream &, vector<Item> &);
void showItems(vector<Item> &);
void split(const string&, char , vector<string>& );

int main()
{
	fstream dataFile;                   // data file
    vector<Item> items;     // dynamically allocate student records

	if (openFileIn(dataFile, "widgets.dat"))
	{
        // get Student data from file into array
    	getItems(dataFile, items);

    	dataFile.close();

        showItems(items);
	}
	else
       cout << "File open error!" << endl;

	return 0;
}

//***********************************************************
// Definition of function openFileIn. Accepts a reference   *
// to an fstream object as an argument. The file is opened  *
// for input. The function returns true upon success, false *
// upon failure.                                            *
//***********************************************************

bool openFileIn(fstream &file, string name)
{
   file.open(name.c_str(), ios::in);
   if (file.fail())
      return false;
   else
      return true;
}


/*
 * getStudent data one line at a time from
 * the file. Parse the line using ',' as delimiter.
 * Save data read to an Item, recorded in 'vs'. 
 */
void getItems(fstream &file, vector<Item> & vs)
{
    string input;	// To hold file input

    // Read item data from file using ',' as a delimiter.
    while ( getline(file, input)) {

        // vector to hold the tokens.
        vector<string> tokens;

        // Tokenize str1, using ' ' as the delimiter.
        split(input, ',', tokens);

        /*
         * copy the tokens to the item record
         */
        Item item;
        item.partNumber  = atoi(tokens.at(0).c_str());
        item.partName =  tokens.at(1);
        item.partQuantity =  atoi(tokens.at(2).c_str());
        item.price =  atof(tokens.at(3).c_str());
        
        vs.push_back(item);
        
        cout << endl;
    }
}

/*
 * show all items
 */
void showItems( vector<Item> & vs)
{
    /* Display the headings for each column, with spacing and justification flags */
    printf("%-8s%-30s%-10s%-8s\n", "partNumber", "partName", "partQuantity", "price");

    // Read item data from file using ',' as a delimiter.
    for ( const Item & item : vs) {

        if (item.partNumber != 0) {

            printf("%-8d%-30s%-10s%-2.2f\n",
                    item.partNumber,
                    item.partName.c_str(),
                    to_string(item.partQuantity).c_str(),
                    item.price
            );
        }

        /* If the id field is zero, then we reached the last student, break
         * out of the for loop.
         */
        else
            break;
    }
}

//**************************************************************
// The split function splits s into tokens, using delim as the *
// delimiter. The tokens are added to the tokens vector.       *
//**************************************************************
void split(const string& s, char delim, vector<string>& tokens)
{  
   // While string is not at end:    
   for(
       int tokenStart = 0, delimPosition = s.find(delim);
       delimPosition - tokenStart != 0;  // if string is not at end
       delimPosition = s.find(delim, delimPosition) // get next delimPosition
    ) {
      // Extract the token.
      string tok = s.substr(tokenStart, delimPosition - tokenStart);

      // Push the token onto the tokens vector.
      tokens.push_back(tok);

      // Move delimPosition to the next character position.
      delimPosition++;

      // Move tokenStart to delmiPosition.
      tokenStart = delimPosition;

   }
}
Further 'simplifications'. Note that with current return optimisations, returning a vector et al now doesn't involve a copy.

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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <cstdio>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>

using namespace std;

struct Item {
	int partNumber;
	string partName;
	int partQuantity;
	double price;

	Item(int p, const string& pnam, int q, double pr) : partNumber(p), partName(pnam), partQuantity(q), price(pr) {}
};

bool openFileIn(fstream&, const string&);
vector<Item> getItems(fstream&);
void showItems(const vector<Item>&);
vector<string> split(const string&, char = ',');

int main()
{
	fstream dataFile;       // data file

	if (openFileIn(dataFile, "widgets.dat"))
	{
		const auto items {getItems(dataFile)};

		dataFile.close();
		showItems(items);
	} else
		cout << "File open error!" << endl;
}

//***********************************************************
// Definition of function openFileIn. Accepts a reference   *
// to an fstream object as an argument. The file is opened  *
// for input. The function returns true upon success, false *
// upon failure.                                            *
//***********************************************************

bool openFileIn(fstream& file, const string& name)
{
	file.open(name.c_str(), ios::in);
	return file.is_open();
}

/*
 * getStudent data one line at a time from
 * the file. Parse the line using ',' as delimiter.
 * Save data read to an Item, recorded in 'vs'.
 */
vector<Item> getItems(fstream& file)
{
	vector<Item> vs;

	// Read item data from file using ',' as a delimiter.
	for (string input; getline(file, input); ) {
		const auto tokens {split(input)};

		vs.emplace_back(atoi(tokens.at(0).c_str()), tokens.at(1), atoi(tokens.at(2).c_str()), atof(tokens.at(3).c_str()));
	}

	return vs;
}

/*
 * show all items
 */
void showItems(const vector<Item>& vs)
{
	/* Display the headings for each column, with spacing and justification flags */
	printf("%-8s%-30s%-10s%-8s\n", "partNumber", "partName", "partQuantity", "price");

	// Read item data from file using ',' as a delimiter.
	for (const auto& item : vs) {
		if (item.partNumber != 0) {
			printf("%-8d%-30s%-10d%-2.2f\n",
				item.partNumber,
				item.partName.c_str(),
				item.partQuantity,
				item.price
			);
		}

		/* If the id field is zero, then we reached the last, break out of the for loop. */
		else
			break;
	}
}

//**************************************************************
// The split function splits s into tokens, using delim as the *
// delimiter. The tokens are added to the tokens vector.       *
//**************************************************************
vector<string> split(const string& s, char delim)
{
	vector<string> tokens;

	// While string is not at end:
	for (
		int tokenStart = 0, delimPosition = s.find(delim);

			delimPosition - tokenStart != 0;  // if string is not at end
			delimPosition = s.find(delim, delimPosition) // get next delimPosition
		) {

		// Push the token onto the tokens vector.
		tokens.push_back(s.substr(tokenStart, delimPosition - tokenStart));

		// Move delimPosition to the next character position.
		delimPosition++;

		// Move tokenStart to delmiPosition.
		tokenStart = delimPosition;
	}

	return tokens;
}

Note that with current return optimisations, returning a vector et al now doesn't involve a copy.


Hello @seeplus, could you tell me how it is feasible returning some data (here some vectors) if they are lying within functions (and hence on stack) without destroying its data base? Thanks.
Its now done by move semantics and/or guaranteed copy elision.

Note vectors aren't 'on the stack'. The data held within a vector is on the heap via dynamic memory.

For containers, only the SBO for std::string is on the stack.
Last edited on
Not to misunderstand, I asked not for the raw data which a vector holds, rather for its 'size', 'reserved', the pointer to the raw data variables and such things. Its somehow fuzzy to me when and if a copy elision will get performed and when not. Therefore I avoided rlying on copy elision so far.
With your suggestion seeplus my file just opens and literally says nothing, if i change the file to one that doesn't exist then i get my error message "File open Error".
Last edited on
Function split() was wrong. I fixed that, and @seeplus' code runs without error at my machine. I have here the -std=c++17 flag set.

Here the fixed 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
//**************************************************************
// The split function splits s into tokens, using delim as the *
// delimiter. The tokens are added to the tokens vector.       *
//**************************************************************
vector<string> split( const string & s, char delim )
{
    vector<string> tokens;

    int tokenStart = 0, delimPosition = s.find( delim );

    // While string is not at end:
    while ( delimPosition != string::npos )
    {

        // Push the token onto the tokens vector.
        tokens.push_back( s.substr( tokenStart, delimPosition - tokenStart ) );

        // Move delimPosition to the next character position.
        delimPosition++;

        // Move tokenStart to delmiPosition.
        tokenStart = delimPosition;

        // Get next delimPosition.
        delimPosition = s.find( delim, tokenStart );
    }
    tokens.push_back( s.substr( tokenStart, string::npos ) );

    return tokens;
}
Idk man this is my output


partNumberpartName                      partQuantityprice

Process returned 0 (0x0)   execution time : 0.013 s
Press any key to continue.

My files supposed to open and display those comma separated values into an array of structures

Part Number, Description, Quantity in Stock, Price
23093, "Basic Widget", 143, 299.99
23355, "Mid-Range Widget", 2556, 749.99
21546, "Advanced Widget", 14, 1599.99
25483, "Special Order Widget", 0, 3100.00


Part Number Description Quantity in Stock Price
----------------------------------------------------------------------
23093 Basic Widget 143 299.99
23355 Mid-Range Widget 2556 749.99
21546 Advanced Widget 14 1599.99
25483 Special Order Widget 0 3100.00
Last edited on
I ran seeplus's code and there's a ton of errors idk what u guys mean by there's no errors.
Function split() was wrong. I fixed that, and @seeplus' code runs without error at my machine. I have here the -std=c++17 flag set
Here is my input file:
123, scull, 4, 5.67
234, bones, 5, 6.78


And this is the program output:
partNumberpartName                      partQuantityprice   
123      scull                        4         5.67
234      bones                        5         6.78

All what's still to do is, fitting the table format.

I compiled with
g++ -O2 -std=c++17 -o record record.cpp

What compiler do you using?
Last edited on
the GNU GCC Compiler, and if that's not it then idk where it is.
like why is my file not inputting the numbers from my file... only the headers
Post your current code, and if you are getting compile/link errors post the error messages as well, all of them exactly as they appear in your development environment.

A couple of notes based on your input file.

First you need to read and discard the first line, the "header" information.

Second your file has embedded quotation marks, this usually means that your strings can have the "delimiter" character as well as the end of line character embedded within those quotes. So you need to be careful about how you process those strings. If you have control of the input file I would recommend removing the quotation marks and any special characters that are embedded within those strings.




Pages: 123