How do you ignore known words in sscanf? - c

I'm trying to strip the data from a string, something like this:
char * fromSocket = "GET /test.html HTTP 1.0\n""Host: www.example.com\n""Client: 127.0.0.1:60000\n";
Where I know that, in this case "HTTP 1.0" "Host:" and "Client" and the semicolon between the client IP and the port will always be there. I'm trying to use a sscanf() like this:
sscanf(conString, "%s %s HTTP 1.0 Host: %s Client: %s:%s", com, loc, hos, cli, port);
But when I test the outputs using this:
printf("%s %s %s %s %s\n", com, loc, hos, cli, port);
I get a bunch of NULLs. How do I ignore the specific words that I know will exist? I looked at some of the pages online, but I think the 1.0 throws the scanner off or whatever. Thanks!

You just put those parts into your format string, and sscanf will assure they're present and accounted for, but won't read them into any variable. For example:
sscanf("GET /test.html HTTP 1.0\nHost: www.example.com\nClient: %16[^:]:%d\n", cli, port);
Also note that white-space (outside a scan-set) in a scanf format string is treated a bit differently from other characters--instead of matching the specified character, it will match an arbitrary amount of white space (so, for example, "\n" in the format string can match " \t\v \r" in the input data). As such, if you need to verify that the new-lines are really new-lines (and not other white-space) you need to change them to something like %*[\n]. If you do that, keep in mind that the norm for most network protocols is a "\r\n" sequence.
If your real question is how to allow (for example) the www.example.com to be an arbitrary string, and you want to assure there's a string there, but don't want to read it into a variable, then you can use a conversion with a * to read but prevent conversion, like: %*s:
sscanf("GET %*s HTTP 1.0\nHost: %*s\nClient: %16[^:]:%d\n", cli, port);

Related

sscanf is unable to scan a string that is given inside quotes

So the concept is this: I want to scan a maximum of 5 strings at a time but it is possible to want to scan just one. This is the point of sscanf,I don't always want to type in 5 things through the console. One line could mean the input of one string or all 5. The problem is when I type:
remove "Just Test"
I get my first string normally,but I end up getting my second string "split" between string1 (now it is:"Just) and string2 (now it is:Test"). This is the code for reference:
fgets(inputbuffer,500,stdin);
sscanf(inputbuffer,"%s %s %s %s %[^\n]s",action,string1,string2,string3,string4);
The problem seems to come from the space between Just and Test. I managed to fix this problem for string4 by putting [^\n],which reads everything till the newline. As you can tell though,this wont obviously work for string1/string2/string3. I am in a pretty tight space cause of this and I am not sure what to do.

c string manipulation for incoming strings

I am new to C and was wondering how I could do something like this:
I have a string coming in like this through a socket (it could vary)
"GET OK 1045 \r\nTHE RED RIDING HOOD"
Now I may get it in chunks of it and not completely like
"GET OK 10"
And later on
"45 \r\nTHE RED RIDING HOOD"
What is the best way to split when it finds the \r\n and store what came before it in a variable and what comes after it in another one.
I have tried strtok() but it just became way to messy and was getting errors
I tried sscanf() but since i may be getting chunks I can never get it to format it correctly into my variables. I am sure there my be a easy way to do this in a while loop but the splitting is what is getting me.
while((items_read = read(sock, stories_buffer, BUF_SIZE)) > 0) {
//how do i check on stories_buffer as it comes and split it based on delimiter \r\n
}
You can wrap the socket into buffered IO and use the stdio functions like fgets() on it:
FILE *f = fdopen(sockfd, "w");
fgets(buf, sizeof(buf), f);
This should be the best option for line-based network protocols.

What is the use of Percent-S (%s) at the end of strings? (Not string formatting)

I'm trying to configure the browser for Jupyter Notebook, and in the .jupyter config file, I am confused by this line.
What is the point of %s at the end of the string?
c.NotebookApp.browser = u'open -a chrome.exe %s'
When I search for %s in strings on the internet, I get the pages related to string formatting (where the string is followed by an additional % variable, to substitute the variable into the string). This is totally unrelated isn't it?
The string is likely passed to sprintf(), which inserts a string parameter in place of %s. See man printf.
In this case, the URL in inserted as a parameter for the open command.
The author of the config file format decided to use string formatting here, so you can insert the URL parameter anywhere in the string, and not only at the end of it, i.e.:
c.NotebookApp.browser = u'/usr/bin/my_browser -new -url %s -some -more -parameters'
Then at runtime of the application, the URL parameter is injected with string formatting:
shellCmd = config.NotebookApp.browser % targetUrl
It is important. Don't delete it.

sscanf with letters, spaces and integers

I'm trying to use sscanf to read a line from a text file and then save the parts of it to the different variables.
The text file looks like that:
name 12345
So I've written the following code:
sscanf(buffer, "%s %d", name, &number);
which works great, but what do I do when name has a space in between? e.g.
name lastname 12345
Or even number?
name the3rd 12345
My sscanf won't work in those two examples. I tried to use the [^] without success or even %*s %[^0-9] %d but didn't work either.
Any help would be appreciated.
I would recommend not trying to force a solution upon the problem. If it's hard with sscanf(), perhaps that's not the proper solution.
I would instead recommend either using an actual regular expression (if you have <regexp.h> it's easy), or using manual parsing techniques to find the last space and splitting the string on that. It can be as easy as strrchr(buffer, ' '); after all.

how to combine multiple *argv into a char* type messge

I wrote a TCP socket client program which allows user to input the IP, port, and message as arguments.
It is like:
./a.out 127.0.0.1 555 test message
My question is, how to combine "test" (argv[3]) and "message" (argv[4]) and more into a char *message?
What you want to do is actually this:
/a.out 127.0.0.1 555 "test message"
By putting quotes around the message, argv[3] will contain the full message. Then you don't have to bother concatenating the arguments together.
You'd have to get the length of your argv strings that you want to combine. Create a char array of that size, and then copy the strings over, using strcpy (preferably the secure version).
You can use strlen to get the lengths of the strings, then allocate a buffer of the appropriate size and use sprintf or strcpy to fill it with your formatted data.
But as Kurtis says, if all you want to do is pass a string containing spaces to your program, then that’s the concern of the shell, not your program. On Unix you should use single quotes ('), and on Windows you can use double quotes (").

Resources