how to use sscanf_s

In the code below you will see I am trying to run a sscanf_s to extract data from a string line. I am not sure why it is not working any help appreciated. It is on line 60.
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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
#include <stdio.h>
#include <dirent.h>
#include <iostream>
#include <string>
#include <fstream>
#include <sstream>



using namespace std;

int main(void)
{


	// Pointer for directory entry
	struct dirent *de;

	// opendir() returns a pointer of DIR type. 
	DIR *dr = opendir(".");

	// opendir returns NULL if couldn't open directory
	if (dr == NULL)
	{
		cout << "Could not open current directory" << endl;
		cin.get();
		return 0;
	}

	while ((de = readdir(dr)) != NULL)
	{
		string name(de->d_name);

		// Search directory for all files ending in .csv
		if (name.size() > 4 && name.substr(name.size() - 4) == ".csv")
		{
			/**
				Open the output CSV file (open once with a tabular CSV)
				Open the input CSV file (config file with paramaters)
				Parse this current file for all parameters(1 paramater per line)
				Apply the algorithm using given bend table
				Flag errors (add pathenthisis around the error values, one column is error,far left side)
				Output one line to output CSV
											  **/

			cout << name << ":\n";
			ifstream fin(name); //bring in file

			string  line;

			// while not end of file
			while (getline(fin, line)) 
			{
				// find "Greenlee" and store that entire line
				if (!strncmp(line.c_str(), "GREENLEE", 8)) 
				{
					char name[12];
					int type;
					cout << " [ " << line << " ] " << endl;
					sscanf_s(line.c_str(), "%s %d", name, &type); //sscanf_s not working
					cout << type << endl;
					cout << name << endl;
		
					continue; 
				}

				// find "vers" and store that line
				if (!strncmp(line.c_str(), "vers", 4))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "units", 5))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "bendtype", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "pipetype", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "pipesize", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "height", 6))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}
				
				if (!strncmp(line.c_str(), "angle", 5))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "length", 6))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}
				
				if (!strncmp(line.c_str(), "straight ", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "h1", 2))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "h2", 2))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "vangle", 6))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "pipe_num", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				
				}

				if (!strncmp(line.c_str(), "seq_bends", 9))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "l1_a1_r1", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}


				if (!strncmp(line.c_str(), "l2_a2_r2", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "l3_a3_r3", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "l4_a4_r4", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "l5_a5_r5", 8))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "conc_bends", 10))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "conc_angle", 10))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "conc_start", 10))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "conc_radi", 9))
				{
					cout << " [ " << line << " ] " << endl;
					continue;
				}

				if (!strncmp(line.c_str(), "PL_batch", 8))
				{
					cout << " [ " << line << " ] " << endl;
				}

			}
			// APPLY Algorithm/ flag errors etc
			// and then start outputting a line to files

		}

	}
	cin.get();
	closedir(dr);

	return 0;
}
Last edited on
This is a horrible mash-up C++ and C. Is there a reason you're using sscanf_s? Could you not just use C++ instead?

Anyway, this code works:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
#include <cstdio>

using namespace std;

int main()
{
    string line("GREENLEE 54");
    char name[12];
    int type;
    sscanf(line.c_str(), "%s %d", name, &type);
    cout << "name= " << name << "  type= " << type << '\n';
}


How do you know that your code doesn't work?
sscanf_s requires the sizes of strings to be passed in (sizes are required for s, S, c, C or [charset]).
 
sscanf_s(line.c_str(), "%s %d", name, 12, &type);

However, you shouldn't use sscanf_s in C++ since there are better ways to do the same thing. For instance:
1
2
3
4
5
6
7
    std::string line{"hello 123"};

    std::string name;   // name should be a std::string
    int type = 0;

    std::istringstream sin(line);
    sin >> name >> type;

Instead of using all of those continues, we would normally just use else if's. And you don't need to use strncmp, either.
1
2
3
4
5
6
7
8
if (line.substr(0, 5) == "hello")
    ...
else if (...)
    ...
else if (...)
    ...
else
    ...

I am using sscanf_s and breaking the cardinal rule because I am a noob and dont know how to parse my input file. For example, I need to parse GREENLEE,1055 Autobend 3D,0,0,,,,,,,,,
and save GREENLEE to a variable, 1055 Autobend 3D to a variable,
0 and 0 to variables and then all of the trailing commas. Any help would be great not sure how to do it and none of the above worked ^

Thanks.
If all you're going to say is "none of the above worked" then what's the point of trying to help you?
I'm done. :-)
Im sorry you are right. I have tried some c++ stuff using istringstream str(line);
and then trying to do a str >> name >> type; but that did not work(assigned too much of the tring to the variables) instead of breaking it up how I wanted. So ,then I thought perhaps a sscanf_s would work perfect but haven't been able to get that to work at all. I also thought maybe using a delimiter would work but the only examples I have seen of using delimiters ends up ignoring commas and I need to store those trailing commas. Thanks again and sorry for such a lazy response earlier, just getting frustrated with something that I thought should be relatively simple with sscanf_s.
Okay, I understand.
Maybe sscanf_s is a good idea after all, but you aren't using it quite right.
Try something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <iostream>
#include <string>

int main() {
    std::string line{"GREENLEE,1055 Autobend 3D,0,0"};
    char a[100], b[100];  // give your c-strings lots of space
    int x=0, y=0;

    sscanf_s(line.c_str(), "%[^,],%[^,],%d,%d",
        a, 100, b, 100, &x, &y);

    std::cout << a << '\n' << b << '\n' << x << '\n' << y << '\n';
}


The %[^,] format says to read characters up to but not including the first comma.
Then the comma skips the comma.
Etc.

Or if you want to be more C++y, then something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <iostream>
#include <sstream>
#include <string>

int main() {
    std::string line{"GREENLEE,1055 Autobend 3D,0,0"};

    std::string a, b;
    int x=0, y=0;

    std::istringstream sin(line);
    std::getline(sin, a, ',');
    std::getline(sin, b, ',');
    sin >> x >> y;

    std::cout << a << '\n' << b << '\n' << x << '\n' << y << '\n';
}

Last edited on
THANK YOU:)

since i needed the trailing commas I just added another string variable for it.

heres the final line I used. Thanks again for your help.
1
2
3
4
5
6
7
8
char name[32];
char machine[32];
char eol[32];
int error;
int reserved;

sscanf_s(line.c_str(), "%[^,],%[^,],%d,%d,%[^\n]", name,40, machine,40, &error, &reserved, eol,40);

Last edited on
Topic archived. No new replies allowed.