This question already has answers here:
Copying a part of a string (substring) in C
(13 answers)
Get a substring of a char* [duplicate]
(5 answers)
Closed 8 years ago.
An MD5 encrypted password is $1$12345678$blahblahblah. The salt is the 8 digit key between the two $ signs after the one. How do i extract those 8?
So far I have char *salt = and i need to make it equal to the third-tenth index of the string.
Your question contains the word "extract" which is somewhat complicated because it is not clear if you want to copy those 8 characters into a new buffer or if you are looking to do something else.
I can imagine that perhaps you simply want to display these 8 characters to a console user. The following code accomplishes this (but probably requires a bit of explanation following):
char *salt = "$1$12345678$blahblahblah";
int from = 3;
int to = 10;
int len = to-from+1;
printf("%.*s\n", len, salt+from);
Printf() and its variants have some pretty powerful string generation/manipulation capabilities. In this case I used a "precision" specifier provided as a parameter for the 's' conversion. If a precision is given for a 's' conversion it is taken to limit the number of characters emitted. I used 'len' via the '*' character to provide this limit in a parametrized fashion. If you know that you are always going to want to emit 8 characters starting from the 3rd (in C we always count from 0 not from 1) then your code can be simplified to the more straightforward form given below:
char *salt = "$1$12345678$blahblahblah";
printf("%.8s\n", salt+3);
Finally, sprintf can be used to copy to another buffer. I'll give a simple form of this task below (note that I changed variable names for clarity; you are extracting the salt from a line of password text):
char *password = "$1$12345678$blahblahblah";
char salt[9]; /* Size of 9 required to hold terminating NULL byte */
sprintf(salt, "%.8s\n", password+3);
/* Now you can use salt for various purposes */
printf ("The salt is %s\n", salt);
Related
This question already has an answer here:
c sscanf with character delimiter
(1 answer)
Closed 2 years ago.
I have a string of the form
"http://something.another.thing:13541/random-text.txt"
I want to extract the "something.another.thing:13541" part out of it, so I am using
sscanf(uri, "http://%s/%*s", host);
To read the specified part into a buffer host. %*s should be ignoring the parts of the string after / right?
The problem is not discarding parts, you need a delimiter [^?]
Try
char *uri = "http://something.another.thing:13541/random-text.txt";
char host[266];
sscanf(uri, "http://%265[^/]", host); // %265 prevents buffer overflows
printf("%s\n", host);
Since a host can not contain more than 255 bytes + say 10 for the port, char host[266]; is what you want to cover all possible cases.
Another option is to get the maximum size with getconf HOST_NAME_MAX and pass it to the program if you are under some linux.
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 4 years ago.
Improve this question
In a group assignment, we have to read input which only consist of the (small) letters a-z and the characters have a max length of 255. I wanted to check with getchar and ASCII, but my partner found a solution using sprintf and scanf, which I do not totally understand:
#include <stdio.h>
int main() {
int result = 0;
unsigned int length = 255;
char input[257];
result = readInput(input, &length);
return 1;
}
int readInput(char *output, int *length) {
char format_pattern[15];
sprintf(format_pattern, "%%%u[^\n]%%n", *length);
printf("Max allowed length is %d\n",*length);
scanf(format_pattern, output, length);
printf("Input length is %d\n",*length);
return 1;
}
Output:
Max allowed length is 255
testinput
Input length is 9
How does the format pattern in sprintf and scanf work?
Especially the three %%% before u and the two %% before n - I tried changing this to %u[^\n]%n because two ## would escape the ´%´, but then I get an error so they have to be there.
The only things I figured out are:
the %n can read the characters before it, e.g.:
int var;
printf("Some Text before%n and after",&var);
printf("characters before percent n = %d\n", var);
Output: Some Text before and aftercharacters before percent n = 16
but in my big example above there isn't a pointer variable, where the
amount of text could be stored since *length is for %%%u?
The [^\n] means something like "read till new Line"
I googled a lot but did not find a similiar example - could somebody help me?
Assuming x is a (large enough) char array
sprintf(x, "%%"); // put a single % (and '\0') in x
sprintf(x, "%u", 8); // put 8 (and '\0') in x
sprintf(x, "%%%u", 8); // put %8 (and '\0') in x
Your partner is using sprintf() to dynamically create a format string for scanf(). This is a bit tricky, because the printf and scanf functions use mostly the same formatting language. The reason for the dynamic format creation appears to be to insert a configurable field width into the format. That's clever, but overcomplicated and wholly unnecessary.
How does the format pattern in sprintf and scanf work? Especially the three %%% before u and the two %% before n
%%%u is actually two directives. The first %% causes printf to emit a single % character, and that leaves %u, which I think you recognize. Similarly, the %%n is one directive (%%, as described above) plus a literal 'n' character, which is emitted as-is. The overall sprintf call prepares a format string something like "%255[^\n]%n".
How, then, does the resulting format work with scanf? You should probably read its documentation, available all over, such as here. That one happens to be for the GLIBC implementation, but you're not using anything non-standard, so it should explain everything you need to know about your particular format. Specifically, the 255 that you go to such trouble to introduce is a maximum field width for a field consisting of characters in the "scanset" described by [^\n] -- every character except newline. The %n does not consume any input; instead, it stores the number of characters so far read by that scanf call.
For your purposes, I see absolutely no reason to generate the scanf format dynamically. You are given a maximum field width, so you might as well use it in a literal format string. Even if you wanted a maximum field width specified at runtime, scanf() has a better mechanism than dynamically writing format strings, involving passing the wanted field width as an argument.
Bonus hint: the code you posted is terribly mixed up about where to use *length and where just length in your printf and scanf calls. Where you want to output its value, you must pass the value (length). Where you want scanf to modify the value, you must pass the address where the new value should be stored (*length).
This question already has answers here:
Getting wrong string length
(3 answers)
Closed 4 years ago.
I have this piece of code:
char* input = malloc(sizeof(char)*100);
scanf("%s", input); //let's say that the number of chars in "%s" is 5
How do I calculate how many chars I typed in (5)? I tried by playing around with sizeof(), but couldn't find a solution.
Edit (better explanation): the input variable can host up to 100 chars, but let's say I type in the terminal 'abcde': then it hosts only 5 chars, the other 95 are not taken. I want to calculate that '5'.
You have to find the null terminator.
int i = 0;
while(input[i] != 0) {
++i;
}
//i marks the spot
But yeah, strlen() does a better job, since it has some improved/optimized searching, since it uses word(16/32/64? bit) compare and stuff.
This question already has answers here:
Number of character cells used by string
(6 answers)
Closed 5 years ago.
i have a problem with printf width modifier in C
example:
char a[] = "o", b[] = "l";
printf("%-3s %s", a, b);
console output gives me 3 spaces between strings, but when I change "o" to "ó", console shows 2 spaces between. Every time i use character like "ł", "ó", "ś" in the string, width modifier is shortened by 1 sign, why this happens?
OS X 10.11 (El Captain)
"Special" characters as you are showing them need more bytes (char) to be represented in a string. Your arbitrary limit of 3 is not enough, raise it to some suitable value.
In addition, the way and length that such special characters are represented depends on the system. For portable code you should never make such arbitrary assumptions.
This question already has answers here:
sprintf buffer sizes
(3 answers)
Closed 9 years ago.
I'm having an issue with sprintf in C resetting the value of a counter variable when I run it. Here in a nutshell is what is happening:
int count = 0;
count++;
printf("%d\n", count); // count will equal 1
char title[7];
sprintf(title, "%.3d.jpg", count);
printf("%d\n", count); // count now equals 0 again
Is this normal behavior for sprintf?
title is too small, sprintf is writing beyond the bounds of title, and writing into count, corrupting its value.
Note that title needs to be long at least 8 bytes: 3 for %.3d, 4 for .jpg and 1 for the terminator \0.
As Grijesh Chauhan points out, you can make sure that you never write beyond the allocated size of the string by using snprintf, i.e.:
char title[8];
snprintf(title, sizeof(title), "%.3d.jpg", count);
You simply need more space in the string title: 3 digits+".jpg" = 7 chars, and u need one extra for '\0'(end of the string). Sprintf can change argument in a case such as this(Using sprintf will change the specified variable)
Solution: change
char title[7];
to
char title[8];
You problem is called buffer overflow. sprintf has no idea of the size of title, and write has much as needed, even if it exceeds the boundaries of your array. To fully understand, you also have to know that strings are terminated by a zero. This allows to find the end of a string, without prior knowledge of its true size. This extra zero takes the place of an extra character that you have to consider when dimensioning your buffers.
Consider also the use of snprintf that ensures you are not going over the boundaries of your buffer.