Normally you can print a string in C like this..
printf("No record with name %s found\n", inputString);
But I wanted to make a string out of it, how I can do it? I am looking for something like this..
char *str = ("No record with name %s found\n", inputString);
I hope it is clear what I am looking for...
One option would be to use sprintf, which works just like printf but takes as its first parameter a pointer to the buffer into which it should place the resulting string.
It is preferable to use snprintf, which takes an additional parameter containing the length of the buffer to prevent buffer overruns. For example:
char buffer[1024];
snprintf(buffer, 1024, "No record with name %s found\n", inputString);
You're looking for the sprintf family of functions. Their general format is:
char output[80];
sprintf(output, "No record with name %s found\n", inputString);
However, sprintf by itself is extremely dangerous. It is prone to something called buffer overruns. What this means it that sprintf has no idea how big the output string you provide it is, so it will willingly write more data to it than is available. For example, this will compile cleanly, but will overwrite valid memory—and there is no way to let sprintf know that it's doing anything wrong:
char output[10];
sprintf(output, "%s", "This string is too long");
The solution is to use a function as snprintf, which takes a length parameter:
char output[10];
snprintf(output, sizeof output, "%s", "This string is too long, but will be truncated");
or, if you're on a Windows system, to use the _sntprintf variants and friends, which protect against overflowing of either the input or output strings.
Since this is homework (thanks for tagging it as such) I'll suggest you to look closely at the ...printf() family of functions.
I'm sure you'll find the solution :)
Look into sprintf (see below).
int n = sprintf(str, "No record with name %s found\n", inputString);
Use
sprintf(str, "No record with name %s found\n", inputString);
Related
I have something in my code as below:
This is code for creating a DEVICE in linux under /dev
#define PRINTER_STR "printer_"
char str[32];
snprintf(str, sizeof(str), PRINTER_STR "%s%s", dev->type, "%u");
device_create(mycan_drv.class, parent,
MKDEV(dev->nMajor, dev->nMinor),
dev, str, dev->nMinor);
4th parameter to snprintf which is dev->type is assigned with strings like epson,hp,canon.
Output achieved is something like this :
printer_epson32,printer_hp33,printer_canon34
In the above output strings, I couldnt understand how the numbers like 32,33,34 are built.
I can understand this is because of the 5th parameter "%u" passed to snprintf. But how ?
All the references i got are with max 3 or 4 parameters of snprintf.
Kindly help.
char str[32];
dev->type = "epson";
snprintf(str, sizeof(str), "printer_" "%s%s", dev->type, "%u");
results in:
str = "printer_epson%u".
Then code does:
device_create(..., str, dev->nMinor);
which is really:
device_create(..., "printer_epson%u", dev->nMinor);
and then inside device_create a *printf like function is once again called and it writes dev->nMinor in place of %u. So, like, it's not snprintf that writes the number, the number is written inside device_create. snprintf is used to create the formatting string for device_create and device_create writes that number.
Side note: The "%s%s", dev->type, "%u") looks strange, it could have been just "%s%%u", dev->type);. And anyway for all that it could have just been device_create(...., "%s%u", dev->type, dev->nMinor).
Simpler would be:
snprintf(str, sizeof(str), PRINTER_STR "%s%%u", dev->type);
Since %u is a fixed string, it could be just included in the format. The % needs to be escaped to avoid being interpreted by snprintf.
Whenever I need to assign to a string and I have some word (called variedinput) that is assigned via standard input, socket, etc, I do something like
char buffer[50];
strcpy(buffer, "The ");
strcat(buffer, variedinput);
strcat(buffer, " jumped over the fence.");
Is there some other function that allows me to do something like the following?
function(buffer, "The %s jumped over the fence.", variedinput)
Yes, it is called spnrintf. I your code:
snprintf(buffer, sizeof buffer, "The %s jumped over the fence", variedinput);
The rules for the format string and later arguments are the same as for printf. Of course, you must make sure variedinput actually points to a string in this example.
sprintf(buffer,"",...)?
Write formatted data to string.
http://www.cplusplus.com/reference/cstdio/sprintf/?kw=sprintf
I have a string structured such as "[first something]=[second something"]
I think sscanf would be a way to seperate them!
However, scan never reports the offset properly with %n.
The line of code is something very much like:
char data[100];
char source[] = "username=katy"
int offset=-1;
sscanf([source],"%[^=],%s%n",data,&offset)
printf("sscanf is reporting %s with an offset of %i\n"
)
but the output always looks like:
sscanf is reporting username with an offset of -1
Could someone be so kind as to clear this up for me?
(Yes, I know this leaves us prone to a buffer overflow error - that is garuneteed against a little earlier in the code...)
Your comma in the scanf format string makes no sense. Instead of "%[^=],%s%n", try "%[^=]=%s%n". You should also put field width limits on both of the strings or else you could overflow the destination buffers, and you've passed too few arguments to sscanf (only one of the strings, not the other one).
A corrected version of the code might look like:
char key[100], data[100];
char source[] = "username=katy"
int offset=-1;
sscanf(source,"%99[^=]=%99s%n",key,data,&offset)
printf("sscanf is reporting %s with an offset of %i\n", data, offset);
My question is how do I create a format string that will include an entire line of text including embedded spaces?
I have a buffer defined
char buf[380];
When I read in a line of text, I make sure that buf[378] = '\n'; and `buf[379] = '\0';'
I am editing that buffer and then writing it to an already-opened file using fprintf:
fprintf(outfile, buf);
I am getting this warning when compiling:
ex_split.c: In function ‘main’:
ex_split.c:65:3: warning: format not a string literal and no format arguments [-Wformat-security]
and am not quite sure how to write the format string so all of buf can be written, because, as I remember it %s will stop at the first space, and this data has lots of spaces in it, which I need. It is positionally formatted data.
Addendum
Let me restate the problem. I believe %s will cause fprintf to stop scanning at the first 0x20 character in each line of data, in which there are one or more and usually many space and non-space, readable ASCII data. Are my assumptions correct?
%s stops at a space when scanning as part of a scanf format, not when printing as part of a printf format. fprintf(outfile, "%s", buf); will work just fine for you.
If you're sure that your buf string is safe - that is, it doesn't contain any % escapes that might cause undefined behaviour in printf, you could also just ignore/disable the warning in this case.
Change
fprintf(outfile, buf);
to
fprintf(outfile, "%s", buf);
and it will work as expected.
I have something like this
char string[]="My name is %s";
printf("%s",string,"Tom");
I expect the output to be My name is Tom but I am getting My name is %s
I tried escaping the % character, but it dint work.
What's going wrong here? How shall I have a %s inside a %s?
Try something like this
printf(string,"Tom");
The problem with your method is this -
As soon as printf sees %s format specifier in your format string, it assumes that the next argument in list is a string pointed to by a character pointer, retrieves it and prints it in place of %s. Now, printf doesn't do a recursive replacement and hence
%s inside your string remains as it is and "Tom" is now an extra argument which is just discarded.
There is only one expansion during printf; that means any strings passed to printf except the format strings will be printed verbatim (if at all). That is actually a good thing, because otherwise, it leaves a huge security hole.
The security risk relates to the fact that the format string and the parameter list have to correspond. That means, if an unwanted % makes it to the format string, you will get in trouble:
char ch[50];
fgets(ch, 50, stdin);
printf(ch);
If the user supplies eg. %p %p %p %p, he will be reading data stored on the stack (like the return address and so on), if he supplies %s %s %s, he'll likely crash the program. If he supplies %n, he'll overwrite some data on the stack.
That said, you can just compute the format string if you want:
char ch[50];
char format_prototype[]="My name is %s";
snprintf(ch, 49, "%s", format_prototype);
ch[49]=0;
printf(ch, "Tom");
printf(string, "Tom") maybe?
The problem is with printf("%s",string,"Tom");
line
You should use
char string[]="My name is %s";
printf(string,"Tom");
here you will get the output as
My name is Tom
The first parameter to printf is the format string. The rest are all parameters which will be formatted according to the format string. The format strings do not nest in any way. In other words, even if a string to be formatted happens to contain formatting instruction, it is simply printed and not interpreted as another format string.
If you want to have that kind of formatting indirection, you would have to first generate a new format string (sprintf is useful for that):
char string[] = "My name is %s";
char format[100];
sprintf(format, "%s", string);
and then use the newly generated format string:
printf(format, "Tom");