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

Pages: 123
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
 
// Program to read a CSV file containing company items into an array of structures
//
// Author:
//
// date: 10/18/20
//
//

#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;

    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;
}



[output]
partNumberpartName                      partQuantityprice

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



[/output]
I've also removed the quotation marks inside my input file & have the same result
Okay, so if the only problem is that you're not getting any output you need to find out where things are going wrong.

So start by making sure your split() function is actually doing what you think it is. Start by printing out the vector returned by the function and insure it is what you think it is.

By the way there are easier ways of parsing a CSV file than what you are doing. Have you considered using stringstreams to parse each line into an Item?

Given the original input file with "", this code produces the expected output. I hadn't tried my previous codeas it was just based upon previous and no file sample.

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
#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;
	string input;

	//Remove header line
	getline(file, input);

	// Read item data from file using ',' as a delimiter.
	while (getline(file, input)) {
		const auto tokens {split(input)};
		const auto& nam {tokens.at(1)};
		vs.emplace_back(atoi(tokens.at(0).c_str()), nam.substr(2, nam.size() - 3), 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("%-12s%-30s%-15s%-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("%-12d%-30s%-15d%-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;

	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;
}



partNumber  partName                      partQuantity   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


Note that the code to remove the " is not robust and if the format changes (etc spaces etc) won't work properly.
Last edited on
ahh okay that makes sense, i have one final question, since i'm inputting this from a file, where in the code do i have to make changes to adjust my output file?
Is it this, and you adjust the numbers?

1
2
3

/* Display the headings for each column, with spacing and justification flags */
	printf("%-12s%-30s%-15s%-8s\n", "partNumber", "partName", "partQuantity", "price");
where in the code do i have to make changes to adjust my output file?


What output file?? The 2 printf() statements display to the console (why printf() in a C++ program?). If you want to output to a file, then you'll need to open the file for output and then write the required data to this file. Depending upon how you want to write to the file (fprintf() or C++ output stream) depends upon how you open the output file.

Changing the 2 printf() statements will adjust how the data is displayed in the console window.
Last edited on
1
2
3
4
	int tokenStart = 0, delimPosition = s.find(delim);

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


Be careful, the above code may not work as expected since std::string.find() doesn't return an int.


Also mixing C-stdio functions and C++ streams is not recommended.

I meant adjusting the console window, so that if i change the 3rd column name from "quantity" to "quantity in stock" it won't interfere with the price column. So if i could just move the 4th column over a couple spaces i'd be done
Change the heading printf() till it is as required. Then adjust the format of the data printf() so that the data aligns with the header as required when displayed.
i suppose fprintf() is what is needed
The values next to the percentage?

1
2
* Display the headings for each column, with spacing and justification flags */
	printf("%-12s%-30s%-15s%-8s\n", "Part Number", "Description", "Quantity in Stock", "Price");



Change the heading printf() till it is as required. Then adjust the format of the data printf() so that the data aligns with the header as required when displayed.
fprintf() will output to a specified FILE* stream which will need to have been opened for ouitput. This is the C way to output to a file. The C++ way is to use stream insertion (<<) into an ofstream object.
I'm not really sure what that means lol i'm new to programming
So could i use fprintf() in my main() after showitems?
No, you should be using C++ streams, not the old C stdio methods.

You'll first need to open a file for output (like you did for input). How do you want the data to be written to the file - the same as to the screen or differently?

I want the file i wrote to be written to the new file called prog2.out i'm just not sure where to do that
My teacher wants us to use some of the old C ways as well, that's why i'm confused about some of the stuff you guys are showing me.
I want to keep my original code instead of just mostly using someone elses code. Here is my original format. The only problem with mine is that the console window only shows the headers and one string from inside the file, and says null instead of zero.

Part Number         Description                   Quantity in Stock        Price
25483                "Special Order Widget"       (null)                   3100.00

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


actual 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
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_WIDGETS 20
struct Widget {
    int number;
    string description;
    int quantity;
    double price;
};

bool openFileIn(fstream &, string);
int getWidgets(fstream &, Widget *);
int showWidgets(Widget *);
void split(const string&, char , vector<string>& );

int main()
{
	fstream dataFile;                   // data file
    Widget *widgets = new Widget[MAX_WIDGETS];     // dynamically allocate student records

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

    	dataFile.close();

        showWidgets(widgets);
	}
	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 Student record pointed to
 * by s_ptr;
 */
int getWidgets(fstream &file, Widget *s_ptr)
{
    string input;	// To hold file input
    int count = 0;

    // Read student data from file using ',' as a delimiter.
    while (count < MAX_WIDGETS && 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 student record
         */
        s_ptr->number  = atoi(tokens.at(0).c_str());
        s_ptr->description =  tokens.at(1);
        s_ptr->quantity =  atoi(tokens.at(2).c_str());
        s_ptr->price =  atof(tokens.at(3).c_str());

        count++;
        cout << endl;
    }
}

/*
 * show all widgets
 */
int showWidgets(Widget *s_ptr)
{
    /* Display the headings for each column, with spacing and justification flags */
    printf("%-20s%-30s%-25s%-8s\n", "Part Number", "Description", "Quantity in Stock", "Price");

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

        if (s_ptr->number != 0) {

            printf("%-20d%-30s%-25s%-2.2f\n",
                    s_ptr->number,
                    s_ptr->description.c_str(),
                    s_ptr->quantity,
                    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);
      }
   }
}

Pages: 123