Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm currently learning strings in C, and a question arose: why doesn't the C developers make strncpy null terminated automatically?
For example in the implementation of strncpy, why didn't people who make C language add this line:
// dest denotes the destination string
dest[n - 1] = '\0';
in order to make strncpy safer?
strncpy was never intended to be a "safe alternative" to strcpy, though that is the impression a lot of new C programmers get since it does take a "size" parameter. The third argument is for the number of characters to be read from the source buffer, not the maximum capacity of the destination buffer.
There are few use cases today for which strncpy is the best choice for copying data from one buffer to another. If you do require a safe alternative to strcpy, you could use snprintf like so:
snprintf(dest, len_dest, "%s", src);
Its done this way, because you may want to overwrite just the first words of a sentence.
It is null terminated if you don't reach the count. See quote below (https://en.cppreference.com/w/c/string/byte/strncpy)
Copies at most count characters of the character array pointed to by
src (including the terminating null character, but not any of the
characters that follow the null character) to character array pointed
to by dest.
It is only unterminated if you reach count before terminating null character. You can't add terminating null character at the capacity because that would be outside of array bounds.
You may want to look into strlcpy which will do what you want but is not part of the standard library.
Related
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 need something like strlen but the string is filled with only null-terminators "\0\0\0\0\0\0\0" and I need to fill it with another character up until (not including) the last \0 like so "FFFFFF\0". Is there a way to calculate the size without errors?
I had to implement bzero for a school project called "libft". Then I was tasked with implementing strcpy and I saw in the man pages that dest needs to be large enough to receive the copy of src so I want to account for a situation where bzero was used on dest and strcpy doesn't allow me to pass the size of dest as a parameter. I was just wondering (out of curiosity) how I would know how big dest is because I know that strcpy does not account for this. There is a warning in the man page "Beware of buffer overruns! (See BUGS.)".
I realise now that this might be impossible in C.
What you're asking is whether you can know how much memory has been allocated.
If it was allocated with malloc, no.
If it's an array allocated on the stack, like char foo[10], yes you can use sizeof(foo), but that doesn't tell you anything you didn't already know.
If you need to know the allocated size of the string, you need to remember it at allocation time and pass it around. You can use an extra variable, or you can make a struct which has both the string and size.
No, there is no generic way. If your char * input fulfils *input == '\0', then it is a null terminated string of size zero, and we cannot know whether input[n] is valid for any n > 0.
However, if you had control over the allocation of input or any other hint, you can use that information, e.g.
input = malloc(N);
/* use N */
Otherwise, it's completely opaque.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 5 years ago.
Improve this question
Can someone explain me this format in C language?
fscanf(file_name,"%20[^\n]%*20c%ld%*c%d%*16c",name,&idE,&cod);
I don't understand what %20[^\n] means.
As noted in the comments, the %20[^\n]scan set conversion specification means that the code will read not more than 20 characters that aren't a newline, null terminating the string (using the 21st byte if necessary). The scan set conversion is complete at the ] — there are special rules when you need to include ] in the scan set. See the POSIX scanf() manual for the full details.
Note that there are various scenarios. First, the scan set won't skip leading white space (and it plus %c and %n are the only three conversion specifications that don't skip white space).
Suppose that the next character is a newline: the conversion fails because there must be at least one character that matches for it to succeed.
Suppose instead that the next few characters are not newlines, but there is a newline before 20 characters are read. Those characters will be read into the string, which will be null terminated.
Alternatively, suppose that the next few characters are not newlines, but there is a newline (immediately) after the 20th character. There will be 20 characters in the string that's read, plus a null terminator, and the newline will be processed by the next part of the format string. In the question, that's %*20c, which means "read 20 characters, including white space, but do not assign to any variable". If, instead of %*20c, the character was c, then the match of the c would fail; the next character is a newline. You'd know because scanf() would return just 1, not 2 or more.
The other alternative is that there are more than 20 non-newlines to read; 20 of them will be saved into the variable associated with the scan set, and the following characters will be matched (or not) by the subsequent characters or conversion specifications in the format string.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 6 years ago.
Improve this question
I was writing a simple program and created an array to store 4 integers. Then I used a for loop to assign them; right after that I used the gets() function to get a string; after using the gets() function the first integer on the array would always become a 0. I even printed the variable on the screen before and after the gets() to confirm.
The only thing that fixed it was dynamically allocating the array, so now I want to know if I should always allocate arrays dynamically to prevent this kind of issue?
code:
int nums[4];
int i = 0;
char symbols[3];
for(i=0;i<4;i++){
scanf("%d", &nums[i]);
}
fflush(stdin);
gets(symbols);
calculate(nums, symbols);
No, you should not.
You should allocate arrays dynamically if you don't know their size at compile-time.
If you know the size at compile-time, allocate it statically.
In both cases you should think twice about the size - e.g. if you forget about the '\0' at the end of a C-String you will end up writing in memory you didn't allocate.
In your program, the problem is that you use gets() which is unusably dangerous. It almost certainly overflowed your string, leading to undefined behaviour. In your program, the undefined behaviour manifested itself as an unexpected change to the array of integers. Using dynamic memory allocation changed where the array was stored compared to the string; it changed the undefined behaviour, but didn't fix the problem (which is that you overflowed your string buffer and invoked undefined behaviour when you did so).
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
I am trying to memcpy 'x' bytes from one array to another starting from some some offset within the array
strlen(buf) // source array already contains 144 bytes
// len - 500 bytes
memcpy(&buf[start], &content[no_of_byes], len)
After this operation on performing strlen(buf), I am getting total of 752, instead of 644. I do not understand the reason.
I even tried copying 500 bytes from content array into another buffer2 and then copying it into buffer, still same result.
strlen tries to calculate the length of a string, in the sense that it keeps on counting bytes from the beginning of the buffer till encounters a '\0' whereas memcpy works only with bytes.
I guess your problem stems from not understanding this.
You may be having a string of 752 and are trying copy some of the bytes inbetween from an offset to the beginning of the buffer (this info not very clear from your question). But, in this process, your '\0' probably remains at the same place leading to the strlen giving the same result.
My suggestion is to differentiate strings and normal buffers and use appropriate system calls for these two operations.
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 8 years ago.
Improve this question
I'm trying to take user input using the getline() function. I store the input and point to it with a char *pointer.
Now I want to split the string at the white space, if there is any, but I can't change a string literal. So my idea was to transfer a copy of the input to a char array so I could then play around with it. The only issue is I don't know the size of the users input yet so I can't specify the size of the array I want.
Any ideas how I can get around this, I'm probably missing something, I'm new to C from a Java background.
Many Thanks!
You read the line, figure out its size, then make a copy of that size.
If you store a user input with some function getline (there is no such a function in C Standard) then you can split it into tokens by using standard C function strtok declared in header <string.h> If you do not want to change the original string then you can write the required function yourself by means of searching blank and non-blank characters in the string.