Printing an array of u_chars - c

I have an array of u_chars and I want to print it using printf. I don't know the size of the array:
u_char *ip_p;
printf("%s", ip_p); // EXC_BAD_ACCESS D:<
I want to print this. How can I do this?

That can't be done. A pointer doesn't magically contain information about the size of the data pointed to.
If there's no convention (a terminator byte, or a length encoded somewhere), you can't know how much data is valid, and thus how much to print.

If you don't know the size, how do you expect printf to know? Fix your code to pass the size as an additional argument. Then you can use:
printf("%.*s", size, buf);
However it looks like your data might not be text but binary. If so, I question the value of printing it with printf...

If ip_p is NUL terminated, your code works. Looking the comment in your code fragment I would say it isn't terminated...

If you don't know the size of the data how can you hope to use it? The size must have been available somewhere otherwise how did it get put there!? You must either know the size or have a sentinel value such as a nul character.
If it is not nul terminated, then "%s" is an inappropriate format specifier. Also if the u_char values are not all printable characters, you should not use %s or even %c. You might use %c and substitute non-printing characters with another.

Related

Why can i not use %s instead of %c?

The whole function the question is about is about giving a two dimensional array initialized with {0} as output and making a user able to move a 1 over the field with
char wasd;
scanf("%c", &wasd);
(the function to move by changing the value of the variable wasd is not important i think)
now my question is why using
scanf("%s", &wasd);
does only work partly(sometimes the 1 keeps being at a field and appears a 2nd time at the new place though it actually should be deleted)
and
scanf("%.1s", &wasd);
leads to the field being printed out without stop until closing the execution program. I came up with using %.1s after researching the difference between %c and %s here Why does C's printf format string have both %c and %s?? If one can figure out the answer by reading through that, i am not clever or far enough with c learning to get it.
I also found this fscanf() in C - difference between %s and %c but i do not know anything about EOF which one answer says is the cause of the problem so i would prefer getting an answer without it.
Thank you for an answer
Simple as that, %s is the conversion for a (non-empty) string. A string in C always ends with a 0 byte, so any non-empty string needs at least two bytes. If you pass a pointer to a single char variable, scanf() will just overwrite whatever is in memory after that variable -- you cause undefined behavior and anything can happen.
Side note, scanf("%s", ..), even if you give it an array of char, will always overflow the buffer if something longer is entered, therefore causing undefined behavior. You have to include a field width like
char str[10];
scanf("%9s", str);
Best is not to use scanf() at all. For your single character input, you can just use getchar() (be aware it returns an int). You might also want to read my beginners' guide away from scanf.
A char variable can hold only one byte of memory to hold a single character. But a string (array of characters) is different from a char variable as it is always ended with a null character \0 or numeric 0. So in scanf you specifically mentioned whether you are reading a character or a string so that scanf can add a null character at the end of a string. So you are not suppose to use a %s to read a value for a char variable

Why does C's printf format string have both %c and %s?

Why does C's printf format string have both %c and %s?
I know that %c represents a single character and %s represents a null-terminated string of characters, but wouldn't the string representation alone be enough?
Probably to distinguish between null terminated string and a character. If they just had %s, then every single character must also be null terminated.
char c = 'a';
In the above case, c must be null terminated. This is my assumption though :)
%s prints out chars until it reaches a 0 (or '\0', same thing).
If you just have a char x;, printing it with printf("%s", &x); - you'd have to provide the address, since %s expects a char* - would yield unexpected results, as &x + 1 might not be 0.
So you couldn't just print a single character unless it was null-terminated (very inefficent).
EDIT: As other have pointed out, the two expect different things in the var args parameters - one a pointer, the other a single char. But that difference is somewhat clear.
The issue that is mentioned by others that a single character would have to be null terminated isn't a real one. This could be dealt with by providing a precision to the format %.1s would do the trick.
What is more important in my view is that for %s in any of its forms you'd have to provide a pointer to one or several characters. That would mean that you wouldn't be able to print rvalues (computed expressions, function returns etc) or register variables.
Edit: I am really pissed off by the reaction to this answer, so I will probably delete this, this is really not worth it. It seems that people react on this without even having read the question or knowing how to appreciate the technicality of the question.
To make that clear: I don't say that you should prefer %.1s over %c. I only say that reasons why %c cannot be replaced by that are different than the other answer pretend to tell. These other answers are just technically wrong. Null termination is not an issue with %s.
The printf function is a variadic function, meaning that it has variable number of arguments. Arguments are pushed on the stack before the function (printf) is called. In order for the function printf to use the stack, it needs to know information about what is in the stack, the format string is used for that purpose.
e.g.
printf( "%c", ch ); tells the function the argument 'ch'
is to be interpreted as a character and sizeof(char)
whereas
printf( "%s", s ); tells the function the argument 's' is a pointer
to a null terminated string sizeof(char*)
it is not possible inside the printf function to otherwise determine stack contents e.g. distinguishing between 'ch' and 's' because in C there is no type checking during runtime.
%s says print all the characters until you find a null (treat the variable as a pointer).
%c says print just one character (treat the variable as a character code)
Using %s for a character doesn't work because the character is going to be treated like a pointer, then it's going to try to print all the characters following that place in memory until it finds a null
Stealing from the other answers to explain it in a different way.
If you wanted to print a character using %s, you could use the following to properly pass it an address of a char and to keep it from writing garbage on the screen until finding a null.
char c = 'c';
printf('%.1s', &c);
For %s, we need provide the address of string, not its value.
For %c, we provide the value of characters.
If we used the %s instead of %c, how would we provide a '\0' after the characters?
Id like to add another point of perspective to this fun question.
Really this comes down to data typing. I have seen answers on here that state that you could provide a pointer to the char, and provide a
"%.1s"
This could indeed be true. But the answer lies in the C designer's trying to provide flexibility to the programmer, and indeed a (albeit small) way of decreasing footprint of your application.
Sometimes a programmer might like to run a series of if-else statements or a switch-case, where the need is to simply output a character based upon the state. For this, hard coding the the characters could indeed take less actual space in memory as the single characters are 8 bits versus the pointer which is 32 or 64 bits (for 64 bit computers). A pointer will take up more space in memory.
If you would like to decrease the size through using actual chars versus pointers to chars, then there are two ways one could think to do this within printf types of operators. One would be to key off of the .1s, but how is the routine supposed to know for certain that you are truly providing a char type versus a pointer to a char or pointer to a string (array of chars)? This is why they went with the "%c", as it is different.
Fun Question :-)
C has the %c and %s format specifiers because they handle different types.
A char and a string are about as different as night and 1.
%c expects a char, which is an integer value and prints it according to encoding rules.
%s expects a pointer to a location of memory that contains char values, and prints the characters in that location according to encoding rules until it finds a 0 (null) character.
So you see, under the hood, the two cases while they look alike they have not much in common, as one works with values and the other with pointers. One is instructions for interpreting a specific integer value as an ascii char, and the other is iterating the contents of a memory location char by char and interpreting them until a zero value is encountered.
I have done a experiment with printf("%.1s", &c) and printf("%c", c).
I used the code below to test, and the bash's time utility the get the runing time.
#include<stdio.h>
int main(){
char c = 'a';
int i;
for(i = 0; i < 40000000; i++){
//printf("%.1s", &c); get a result of 4.3s
//printf("%c", c); get a result of 0.67s
}
return 0;
}
The result says that using %c is 10 times faster than %.1s. So, althought %s can do the job of %c, %c is still needed for performance.
Since no one has provided an answer with ANY reference whatsoever, here is a printf specification from pubs.opengroup.com which is similar to the format definition from IBM
%c
The int argument shall be converted to an unsigned char, and the resulting byte shall be written.
%s
The argument shall be a pointer to an array of char. Bytes from the array shall be written up to (but not including) any terminating null byte. If the precision is specified, no more than that many bytes shall be written. If the precision is not specified or is greater than the size of the array, the application shall ensure that the array contains a null byte.

String format works in fprintf but doesn't work in sprintf, gives segmentation fault

fprintf(fp,"IP: %d: %.*s\n",
ip,
strstr(strstr(p->data, "User-Agent:"),"\n") - strstr(p->data, "User-Agent:"),
strstr(p->data, "User-Agent: ") );
fclose(fp);
Hi All, as you can see, in the above statement, I am trying to write off just the User Agent header from a char pointer which contains the entire http packet data. The thing is, After fiddling with the string format, I came up with this %.*s format which lets me, dynamically select the number of characters to be printed to the file, and then prints them. What the code is basically doing is, first, it's printing an int, then the number of chars from the occurrence of "User-Agent:" to the very next occurrence new line character is passed, and that amount of chars are then passes starting at where the "User-Agent:" starts, from the entire packet data string. I know it's all pretty messy, but it's working fine. Except that it's not working in sprintf.
Please save all my hard word! Any help is appreciated!
char *stat;
sprintf(stat,"%.*s\0",
strstr(strstr(p->data, "User-Agent:"),"\n") - strstr(p->data, "User-Agent:"),
strstr(p->data, "User-Agent: ")) ;
You are not allocating memory for stat. Try
char *stat = malloc(MAXLEN);
snprintf(stat, MAXLEN, ...);
^ ^
When you use sprintf, you need an array of characters to write into. You're writing to an uninitialized pointer.
Try this instead:
char stat[200];
sprintf(stat, etc...
Well, you are trying to write the data into uninitialized unallocated random memory location. Now that can't possibly work.
Either do:
char stat[SUFFICIENTLY_LARGE_NUMBER];
snprintf(stat, SUFFICIENTLY_LARGE_NUMBER, ...);
or:
char *stat = malloc(SUFFICIENTLY_LARGE_NUMBER);
snprintf(stat, SUFFICIENTLY_LARGE_NUMBER, ...);
and make sure "SUFFICIENTLY_LARGE_NUMBER" is enough bytes that the string fits in and not unnecessarily huge.
PS: snprintf, because your format does not include length limits. If it does, sprintf is OK, but never ever use sprintf with unlimited %s. Your %.*s, while formally limited, is not enough, because the expression will happily return more than the size of the allocated buffer, so you need another check to avoid overruning it.

K&R 3-2 overflow problem

I'm going through K&R and 3-2 looks like it would be easy to get into a buffer overflow
Write a function escape(s,t) that converts characters like newline and tab into visible escape sequences like \n and \t as it copies the string t to s. Use a switch
If I replace the byte '\n' with '\' and 'n', the size of s could potentially be quite a bit bigger than the source string.
I could just write this program and ignore the overflow but I would rather not.
I'm having issue wrapping my head around how to handle this?
I'm thinking having a fixed buffer size, perhaps something out of limit.h, and flushing the buffer to stdio when it gets full?
I believe the entire point of the exercise is to teach you that when you're dealing with something like this you either need to:
Shoot too high (make a buffer double the size of the original)
Take extra time (an extra pass) and pre-compute the required size of the buffer.
s will never be longer than twice the length of t. Since this is an exercise apparently meant to help you learn to use switch, I think it'd be fine to assume that the caller passes a string in s that's of sufficient length. Or, if s is of type char** (or similar), then you're meant to allocate the string, in which case you can allocate a string of the proper size.
In a real-world function, you'd probably have another parameter that indicates the maximum length for the destination string.
try adding a size parameter, so you know the size of the target buffer. If you pass a pointer to that parameter, you can return some kind of error value if the buffer is too small and pass the needed size back through the size param. Something like:
int escape(size_t *size, char *out, const char *in);

help with strings in C

I'm studying for an exam and I need some help with strings
Assume the following declarations, and further assume that string.h is uncluded
char rocky[21], bw[21], boris[21];
int result;
a.) Write a scanf statement that would enable the string Beauregard to be read into rocky
my answer= scanf("%s", &rocky);
b.) Assuming that the text Beauregard is the only thing on th eline of standard input, write a statement to read in the text and store it in rocky using an alternative to scanf
my answer= gets (Beauregard);
strcpy(rocky);
c.) assuming that the text read in is Beauregard, what is the value of result after the following statement is executed?
result=strlen(rocky);
my answer= i have no clue..
d.) what does the following statment do?
strcpy(boris, rocky);
answer= makes a copy of the string..(dont know much more than that)
e.) what does the following statement do? What are the values of rocky and bw?
strncpy(bw,rocky,3);
my answer= not a clue
help is much appreciated, and an explanation would also help :)
Thanks!
a. Arrays and pointers are closely related in C. In particular, the name of an array decays to a pointer to the first element of the array, so your answer should be
scanf("%s", rocky); /* note the lack of an & in front of rocky */
b. gets(Beauregard) doesn't really make sense. The gets function reads a string from standard input (think, "keyboard") and stores it in the character array pointed to by the argument you pass it. So you're supposed to assume the user will type "Beauregard", and you should read it into the rocky array with
gets(rocky);
c. strlen returns the length of the string, not including the trailing \0 character, so in this case, 10.
d. strcpy just copies the contents of the rocky array into the boris array, so they'd both contain "Beauregard".
e. strncpy works like strcpy, but only copies up to n characters (where n is the last argument, so in this case, bw would contain "Bea" without a terminating null character.
Note that several of these statements are really bad ideas in any real program. There is never a reason to use gets, for example, as any use of gets opens up security flaws. You should always use fgets instead. The scanf function can be used safely if you specify the width, but you haven't done so here. I mention these things just in case your teacher has covered them and you've forgotten.
strlen returns the length of the C string. strlen("Beauregard"); would return 10 because the string is 10 characters long.
strcpy just copies a string, you're right.
strncpy allows you to specify the maximum number of characters you want. So if you pass it 3, you'll get 3 characters and the null terminator on the end of your string.
strlen(rocky) is going to return the string length of what is pointed to by rocky. The number of letters that make up 'Beauregard'.
strncpy(bw, rocky, 3) copies the first 3 letters from the string pointed to by rocky into bw.
You should read man pages for strlen, strcpy and strncpy.
c.) strlen counts until it reaches the terminating null character, \0. So the answer would be 10, because there are 10 letters in Beauregard.
Strlen
d.) Yes, it copies a string. More specifically, it copies rocky into boris. I'm not sure what else they would want you to give as part of an answer there...
e) It copies the first 3 characters of rocky into bw. However, it does NOT add a terminating null character. strncpy

Resources