sscanf() with two string parameters [closed] - c++

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I want to create the command /kick playername reason in C++, so I tried it:
if (IPlayer.IsOnline() && IPlayer.GetAdmin() >= 3
&& sscanf(command, "/kick %[a-z | A-Z | 0-9/<>|.,~*;`:!'^+%&/()=?_-£#${[]}€] %[a-z | A-Z | 0-9/<>|.,~*;`:!'^+%&/()=?_-£#${[]}€]",
&playername, &reasonkick) == 2)
But nothing happens when I use the command in game. Is the syntax wrong?

sscanf() does not support regular expressions. The way you are using the %[] placeholder is indeed wrong syntax. Try this instead:
if (IPlayer.IsOnline() &&
(IPlayer.GetAdmin() >= 3) &&
(sscanf(command, "/kick %N[^ ] %Ms", playername, reasonkick) == 2))
{
...
}
Where N and M are the max widths of the playername and reasonkick buffers, respectively, eg:
char playername[51] = {};
char reasonkick[129] = {};
if (IPlayer.IsOnline() &&
(IPlayer.GetAdmin() >= 3) &&
(sscanf(command, "/kick %50[^ ] %128s", playername, reasonkick) == 2))
{
...
}
The %N[^ ] will scan the input string until a space character is encountered or N characters have been scanned. No need to specify all of the individual characters that could be encountered. The %Ms will scan the rest of the input string until the end of the string is reached or until M characters have been scanned. If needed, you can use %M[^ ] for that parameter instead.
However, in C++, this would be better handled using std::istringstream and std::getline(), instead of sscanf(), eg:
if (IPlayer.IsOnline() && (IPlayer.GetAdmin() >= 3))
{
std::istringstream iss(command);
std::string cmd;
if (std::getline(iss, cmd, ' ') && (cmd == "/kick"))
{
std::string playername, reasonkick;
if (std::getline(iss >> std::ws, playername, ' ') &&
std::getline(iss >> std::ws, reasonkick, ' '))
{
...
}
}
}

Related

C++ - How can i split up 3 lines safed in string called "result" and create a oneline "synonym" for all 3 strings. - C++ [duplicate]

This question already has answers here:
Parse (split) a string in C++ using string delimiter (standard C++)
(33 answers)
Closed 2 years ago.
So, Hello Guys.
I have a function, which reads the Diskdrive Serialnumber.
I get a output like this:
SerialNumber A6PZD6FA 1938B00A49382 0000000000000
(thats not my serialnumber, just the format)
So now, i want to split the 3 numbers, or strings, however i call it you know what i mean, and save it in in three independent strings.
string a = {A6PZD6FA this value} string b = {1938B00A49382 this value} string c = {0000000000000 this value}
After that, i want to create a oneline "synonym" for all 3 strings. So i mean,
string synonym = 04930498SV893948AJVVVV34
something like this.
If you have the original text in a string variable, you can use a std::istringstream to parse it into constituent parts:
std::string s = "SerialNumber A6PZ etc etc...";
std::istringstream iss{s};
std::string ignore, a, b, c;
if (iss >> ignore >> a >> b >> c) {
std::string synonym = a + b + c;
...do whatever with synonym...
} else
std::cerr << "your string didn't contain four whitespace separated substrings\n";

C++ find whitespaces in substring [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I want to know how can I find empty or whitespaces within substring in C++. For example:
string str = "( )"; // or str = "()"
Here, I want to make sure there is always something in between parenthesis. Function isspace() takes only one character so I have to search in loop. Is there any better way to do this? Thanks for your help.
You can use std::string::find() to find the ( and ) characters, then use std::string::find_first_not_of() to check for any non-whitespace characters between those indexes.
string str = "( )"; // or str = "()"
string::size_type idx1 = str.find("(");
if (idx1 != string::npos) {
++idx1;
string::size_type idx2 = str.find(")", idx1);
if (idx2 != string::npos) {
string tmp = str.substr(idx, idx2-idx1);
string::size_type idx3 = tmp.find_first_not_of(" \t\r\n");
if (idx3 != string::npos) {
...
}
}
}

How can I ignore certain strings in my string centring function?

N.B: Directly connected to a problem I had a few years ago, but I'd like to resolve the first issue there which wasn't otherwise part of the question, so please don't flag it as a duplicate of my earlier question.
I have a string centring function that centres the given string according to the given width (which is 113 characters):
std::string center(std::string input, int width = 113) {
return std::string((width - input.length()) / 2, ' ') + input;
}
I am using a game SDK in order to create a gameserver modification, and this game SDK supports coloured strings in the game's command console, which are denoted using a dollar sign and a number from 0-9 (i.e, $1) and are not printed in the console itself.
The string centring function above treats these markers as part of the total string, so I want to add the total amount of characters these markers take up to the width so that the string is actually centred.
I have tried modifying the function:
std::string centre(std::string input, int width = 113) {
std::ostringstream pStream;
for(std::string::size_type i = 0; i < input.size(); ++i) {
if (i+1 > input.length()) break;
pStream << input[i] << input[i+1];
CryLogAlways(pStream.str().c_str());
if (pStream.str() == "$1" || pStream.str() == "$2" || pStream.str() == "$3" || pStream.str() == "$4" || pStream.str() == "$5" || pStream.str() == "$6" || pStream.str() == "$7" || pStream.str() == "$8" || pStream.str() == "$9" || pStream.str() == "$0")
width = width+2;
pStream.clear();
}
return std::string((width - input.length()) / 2, ' ') + input;
}
The goal of the above function is to iterate through the string, add the current character and the next to an ostringstream, and evaluate the ostringstream.
This didn't exactly do as I wanted:
<16:58:57> 8I
<16:58:57> 8IIn
<16:58:57> 8IInnc
<16:58:57> 8IInncco
<16:58:57> 8IInnccoom
<16:58:57> 8IInnccoommi
<16:58:57> 8IInnccoommiin
<16:58:57> 8IInnccoommiinng
<16:58:57> 8IInnccoommiinngg
<16:58:57> 8IInnccoommiinngg C
<16:58:57> 8IInnccoommiinngg CCo
<16:58:57> 8IInnccoommiinngg CCoon
<16:58:57> 8IInnccoommiinngg CCoonnn
<16:58:57> 8IInnccoommiinngg CCoonnnne
(snippet from server log)
Here's a brief summary of the issue:
I think I might be missing how iteration works; what am I missing, and how can I make this function work in the way I want it to?
So, what you are really trying to do is count the instances of $N in your string, where N is a decimal digit. To do this, just look in the string for instances of $ using std::string::find, and then check the next character to see if it is a digit.
std::string::size_type pos = 0;
while ((pos = input.find('$', pos)) != std::string::npos) {
if (pos + 1 == input.size()) {
break; // The last character of the string is a '$'
}
if (std::isdigit(input[pos + 1])) {
width += 2;
}
++pos; // Start next search from the next char
}
In order to use std::isdigit, you need to first:
#include <cctype>

c# How to Split CSV string which have string with commas [duplicate]

This question already has answers here:
Reading CSV files using C#
(12 answers)
Closed 7 years ago.
I have below mentioned CSV string which I need to split using commas .
Input:
A,"Rakesh,Gaur",B,"A,B",Z
OutPut:
A
Rakesh,Gaur
B
A,B
Z
You can't use string split or regular expressions. If you are not going to use a library that is already built, you have to keep track of whether or not you are in_quotes. but as you will find out after you start this: csv parsing is complex. You should use something that is already pre-built. As I recall from my days writing an app that heavily relied on csv, there are escape characters and such, that you will need to account for.
Either way the psuedo code is as follows:
Stack cells = m
in_quotes = false
foreach character in string:
if character != ',' && character != '"':
cells.Top = cells.Top + character
else if character == ',' && in_quotes:
cells.Top = cells.Top + character
else if character == ',':
cells.push("")
else if character == '"' && in_quotes:
in_quotes = false
else if character == '"':
in_quotes = true
I think you can do this using following steps:
string[] words = yourStringInput.Split(',');
foreach (string word in words)
{
Console.WriteLine(word);
}

Differentiate between same strings with different punctuation in C++

I am writing a C++ program to count the frequency of a word occurring in a text file. I am using the isalpha function to separate the words, but isalpha does not differentiate between same strings having different punctuation.
For example: "I own a company. In my company, there are 200 employees. I love my company."
In the above sentence it gives count of company as 3
How do I make it to differentiate the count like:
company 1
company, 1
company. 1
The loop which does the counting:
while(!isalpha(c) && !in.eof())
{
c = in.get();
}
while(isalpha(c))
{
out.push_back(tolower(c));
c = in.get();
}
where 'out' is a string, 'in' is an istream value and c is a char.
[EDIT] Got Solution
while(!isalpha(c) && !ispunct(c) !in.eof())
{
c = in.get();
}
while(isalpha(c) || ispunct(c))
{
out.push_back(tolower(c));
c = in.get();
}
I thought your way was better (I would expect company to have a count of 3).
But if you want to separate words and punctuation is significant, then use isspace() as a separator.
Note: The standard stream >> operator already does this for you.
std::string word;
in >> word;
std::transform(word.begin(), word.end(), word.begin(), ::tolower);