I have the string (45 bytes):
String1 String2000000000001234
I need get three variable from this string:
char * var1="String1";
char * var2="String2";
int var3=1234;
Here 3 part with fixed length (15 bytes). I need save all parts to variable without spaces for strings and without leading zero for integers.
Is this possible with scanf()? How I can to do that?
Not possible with sscanf. First, you need to pass a char array (and size if you use the _s variety) and not just a char pointer (i.e. it needs to have memory associated with it). Second, strings in sscanf terminate by whitespace, and you have none between String2 and 0000. Write a custom parser for this format.
According to this, your problem should be solved by the following format:
%*[^a-zA-Z]%s%*[^a-zA-Z]%[^0]s%*[^1-9]%d
Description:
%*[^a-zA-Z] - skip(do not store) until alphabetical, i.e. skip leading spaces
%s - read first string until spaces
%*[^a-zA-Z] - skip trailing spaces until the next string
%[^0]s - read string util zeros
%*[^1-9] -skip until nonzero digits
%d - finally, read the number
The easiest would probably be:
char var1_buffer[31] = "", var2_buffer[31] = "";
sscanf(string+30, "%d", &var3);
string[30] = '\0';
sscanf(string, "%s%s", var1_buffer, var2_buffer);
var1 = strdup(var1_buffer);
var2 = strdup(var2_buffer);
which requires being able to write to the input string. If that's not possible, you could replace lines 3 and 4 with:
int p1 = 0;
sscanf(string, "%30s %n%30s", var1_buffer, &p1, var2_buffer);
if (p1 > 30)
p1 = 30;
var2_buffer[30-p1] = '\0';
In either case, you should probably add checks of the return value of sscanf to make sure the input string is well-formed.
Related
I have a simple programme that inserts or appends a number of spaces to align text.
f()
{
string word = “This word”;
const string space = “ “;
int space_num = 5; // this number can vary
for (int i = 0; i < space_num; i++)
{
word.insert(0, space);
}
cout << word;
}
Now this works, but I was wondering if there was a more efficient way to do this. Not in terms of optimizing my programme, but more as in standard practice.
I can imagine two potential methods:
1 - Is there a way to create a string of say 20 spaces, and append a portion of those spaces rather than repeatedly adding a single space.
2 – Is there a way to create string with a variable number of spaces and append that?
Yes, both take a number of copies and a character:
word.insert(0, space_num, ' ');
word.append(space_num, ' ');
For aligning text, keep in mind you can use a string stream and the <iomanip> header, such as std::setw as well.
1 - Is there a way to create a string of say 20 spaces, and append a portion of those spaces rather than repeatedly adding a single space.
Yes, try this:
string spaces(20, ' ');
string portionOfSpaces = spaces.substr(0,10); //first 10 spaces
string newString = portionOfSpaces + word;
Generally, you can use substr to get a portion of spaces and do operations with that substring.
2 – Is there a way to create string with a variable number of spaces and append that?
Yes, see string constructor:string (size_t n, char c); and string::append
I have possible inputs 1M 2M .. 11M and 1Y (M and Y stand for months ) and I want to output "somestring1 somestring2.... and somestring12" note M and Y are removed and the last string is changed to 12
Example: input "11M" "hello" output: hello11
input "1Y" "hello" output: hello1
char * (const char * date, const char * somestr)
{
// just need to output final string no need to change the original string
cout<< finalStr<<endl;
}
The second string is getting output as a whole itself. So no change in its output.
The second string would be output as long as M or Y are encountered. As Stack Overflow discourages providing exact source codes, so I can give you some portion of it. There is a condition to be placed which is up to you to figure out.(The second answer gives that as well)
Code would be somewhat like this.
//Code for first string. Just for output.
for (auto i = 0 ; date[i] != '\0' ; ++i)
{
// A condition comes here.
cout << date[i] ;
}
And note that this is considering you just output the string. Otherwise you can create another string and add up the two or concatenate the existing ones.
is this homework? If not, here's what i'd suggest. (i ask about homework because you may have restrictions, not because we're not here to help)
1) do a find on 'M' in your string (using find), insert a '\0' at that position if one is found (btw i'm assuming you have well formatted input)
2) do a find on 'Y'. if one is found, insert a '\0' at that position. then do an atoi() or stringstream conversion on your string to convert to number. multiply by 12.
3) concatenate your string representation of part 1 or part 2 to your somestr
4) output.
This can probably be done in < 10 lines if i could be bothered.
the a.find('M') part and its checks can be conditional operator, then the conversion/concatenation in two or three lines at most.
Here is my practice code:
int integer_part;
char* string_part = (char*)malloc(sizeof(1000));
char* input_string = (char*)malloc(sizeof(1000)+sizeof(int));
cin>>input_string;
sscanf(input_string, "%s %d", string_part, &integer_part);
printf("scan: %s %d", string_part, integer_part);
I am using this code to take input like abc 2012 but the result will be abc 0
Sadly I didn't see where the problem is. Can anyone help me with this a little? thank you
This reads only first space delimited string:
cin>>input_string;
Use this way:
cin>> string_part >> integer_part;
Don't mix C++ and C way of reading from streams.
You can use this way to read string without space delimited:
cin.read ( input_string, sizeof(1000)+sizeof(int) - 1);
size_t read_Len = cin.gcount();
input_string[read_Len] = '\0';
I can understand you need the power of scanf to read data in a given format.
You are misusing sizeof. If you want space for 1,000 characters, you don't want the size of 1,000 itself, you want 1,000 times the size of a character. You can use 1000 * sizeof(char). Since sizeof returns characters (and thus sizeof(char) must be 1) you can just use 1000.
Currently I have a GPS connected to my Arduino chip which outputs a few lines every second. I want to extract specific info from certain lines.
$ÇÐÇÇÁ,175341.458,3355.7870,Ó,01852.4251,Å,1,03,5.5,-32.8,Í,32.8,Í,,0000*57
(Take note of the characters)
If I read this line into a char[], is it possible to extract 3355.7870 and 01852.4251 from it? (Well obviously it is, but how?)
Would I need to count the commas and then after comma 2 start putting the number together and stop at comma 3 and do the same for second number or is there another way? A way to split up the array?
The other problem with this is identifying this line because of the strange characters at it's beginning - how do I check them, because their not normal and behaves strangely?
The data I want is always in form xxxx.xxxx and yyyyy.yyyy and are unique in that form, meaning I could maybe search trough all the data not caring about which line it's on and extract that data. Almost like a preg-match, but I have no idea how to do that with a char[].
Any tips or ideas?
You can tokenize (split) the string on the comma using strtok, and then parse the numbers using sscanf.
Edit: C example:
void main() {
char * input = "$ÇÐÇÇÁ,175341.458,3355.7870,Ó,01852.4251,Å,1,03,5.5,-32.8,Í,32.8,Í,,0000*57";
char * garbage = strtok(input, ",");
char * firstNumber = strtok(NULL, ",");
char * secondNumber = strtok(NULL, ",");
double firstDouble;
sscanf(firstNumber, "%lf", &firstDouble);
printf("%f\n", firstDouble);
}
If you have strange characters at the beginning of the string, then you should start parsing it from the end:
char* input = get_input_from_gps();
// lets assume you dont need any error checking
int comma_pos = input.strrchr(',');
char* token_to_the_right = input + comma_pos;
input[comma_pos] = '\0';
// next strrchr will check from the end of the part to the left of extracted token
// next token will be delimited by \0, so you can safely run sscanf on it
// to extract actual number
How to find the length of the string which also contains string terminating character in between. Example: ABC\0ABC. Is there any inbuilt function present which returns the length?
If the Input string is: ABC\0ABC
Output: 8
Since the end of a C-style string is only detectable because it ends in a '\0' character, what you're asking isn't solvable in a general way. If, like in your example, you know there's exactly one '\0' character in the string, then you can simply do:
x = strlen(string); // length of string before the first '\0'
x += strlen(string + x + 1) + 1; // plus the length of the string after
// the first '\0' plus the '\0' itself.