Click here to Skip to main content
15,943,008 members
Please Sign up or sign in to vote.
1.33/5 (2 votes)
See more:
Hello All,
This question is a part of the question I had previously posted:[Inconsistent file format[^]] , but this is particularly about swscanf_s function.

In the code :
C++
CStdioFile std;
CString    buffer;
wchar_t str1[2046],str2[2046],str3[2046],str4[2046],str5[2046],str6[2046];
double time, lat;
if (std.Open(fname, CFile::modeRead)) // CStdioFile csf;
{
  while (std.ReadString(buffer) )
  {
    int out = 0;
  out = swscanf_s(buffer, (_T("%[^,],%lf,%lf,%[^,],%lf,%[^,],%d,%d,%lf,%lf,%[^,],%lf,%[^,],,%[^,]"),
 // str1, 2046, &sTime, &db1,str2,2046,&db2,str3,2046,&in1,&in2,&db3,&db4,str4,2046,&db5,str5,2046,str6,2046);
  if(out = 15)
  {
   //calculations
  }
  else
   //output the error buffer lines
  }


Since the file is not always of the same format, some files may have more than 3 variable or less. So I used a method to use in the swscanf_s, such that it returns a string.

i.e;
C++
SetValues()
{
  wchar_t str1[2046];
  double time, lat; 
  CString  fmtStr;
  fmtStr.AppendFormat((_T("%[^,],%lf,%lf,%[^,],%lf,%[^,],%d,%d,%lf,%lf,%[^,],%lf,%[^,],,%[^,]"),
   // str1, 2046, &sTime, &db1,str2,2046,&db2,str3,2046,&in1,&in2,&db3,&db4,str4,2046,&db5,str5,2046,str6,2046));  
  return fmtStr;
}

And use this function in the swscanf_s function. Like this :
C++
out = swscanf_s(buffer, SetValues();

But I get an error that says:
Expression: ("Incorrect Format specifier", 0)

The input file format looks like this: $GPS1,145217.00,7434.7369647,N,05713.8922390,W,2,09,0.9,44.94,M,21.98,M,43.2,0081*55
Need some help please
Posted
Updated 20-Aug-12 1:45am
v3
Comments
Raj Indian 24-Aug-12 6:23am    
It seems that you are trying to parse NMEA sentences. In NMEA GPS Data, not always the comma separated values are not null and also there are different types of sentences with it's own unique format. I think you need to parse each of them separately, considering the null tokens also.
Sumal.V 25-Aug-12 5:04am    
Hey thanks.. but the problem is just solved. Looks like you work with GPS data as well... ;)

The problem is not with the conents of the file format! The error message tells yu exactly what the problem is: Inconsistent Format Specifier! You should print out the return value of SetValues(). Its pretty clear that it returns a string that isn't a format string, you do something realy weird inside SetValues(). Note that you are using an already formatted string as a format string in another function call: so in your original format string you should use double '%' character if you want that to be a single '%' when you format next time. Example:
C++
CString s;
s.Format("%%0%dd", 9);
CString t;
t.Format((const char*)s, 1);

In the first format string the %d is a real format specifier and the double '%': "%%0%dd" so the result will be "%09d" that will be a valid format string for the next format operation. Got the double '%' trick?
 
Share this answer
 
Comments
Sumal.V 20-Aug-12 9:03am    
Yes I understood about the %%d but thinking how that applies to my code. But is that a good way of including a formatted string?
pasztorpisti 20-Aug-12 9:08am    
I don't understand you question. Anyway its not clear what do you want to do. Have you checked your own code? What does SetValues() return? If the problem is there then its up to you to fix it.
Sumal.V 20-Aug-12 9:27am    
Well the problem is with my SetValues function. I need to use some other way of parsing the string (and its different formats).
But thank you :)
pasztorpisti 20-Aug-12 9:56am    
Another side note: you should consider using a simple regex library instead of scanf!
Sumal.V 20-Aug-12 10:09am    
Can I have an example please...
You are using a combination of crappy Microsoft classes that were only meant to be used until the STL arrived, and C runtime functions. My overall recommendation is to use proper C++. CString is rubbish and CStdioFile is worse.

Your error relates to the format of the string you're passing in, so we probably need to see the inputs to the C function call you're making ( which is also deprecated, even if you want to use C ), to know what is going wrong.
 
Share this answer
 
Comments
Sumal.V 20-Aug-12 7:46am    
Crappy? :( I don't know! Updated the question just now.
pasztorpisti 20-Aug-12 8:20am    
Don't be afraid, stl is also crappy! :-) My opinion is that the MFC CString is a bit more comfortable, and at least that has format methods! :D The best is if you are good enough to write your own string class that has all the benefits of these, plus more: has refcounting, has format methods, stores data as utf8 and has utf8 compatiblity methods (for example Utf8CharCount), etc...
But I have a good advice for you: Dont write programs that are both Ansi and WideChar compatible, so forgot about the _T() macro and the ansi functions (they are from old times), go pure unicode/utf8 or utf16!
Christian Graus 20-Aug-12 8:22am    
I disagree. The STL is awesome, and the stl:string integrates with it really well. Writing your own string classes is redundant IMO, same with collections. Write one to know how they work, then throw it away and use the standard ones, which can be extended.
pasztorpisti 20-Aug-12 8:50am    
How do you extend it with refcounting or sparse substrings? Not to mention that often you need different kind of strings. stl is general purpose, sometimes isnt smart enough, and its source is ugly. It has only one advantage over a custom string: its interface is known by everybody, but is that a real adavantage with such a primitive type? With small projects its ok to go with stl, with mid-to-large scale I like own stuff more.
Christian Graus 20-Aug-12 9:06am    
The real advantage is, when I look at your code, I know how the class works. When I consume your code, I am using the same types.
I only simplified my code by checking the fileformats:
C++
if (swscanf_s(buffer,  _T("%[^,],%lf,%lf....."),val1, 2046, &val2, &val3............) == 14)
{
// Push values into the vector of type Class- that holds these variables 
}

else if (swscanf_s(buffer,  _T("%[^,],%lf......"),val1, 2046, &val2, &val3............) == 10)
{
// Push values into the vector of type Class- that holds these valriables 
}

Then added functions to process only the variables required, Which is read from the memory. 
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900