I am doing something in C which requires use of the strings (as most programs do).
Looking in the manpages, I found, at string(3):
SYNOPSIS
#include <strings.h>
char * index(const char *s, int c)
(...)
#include <string.h>
char * strchr(const char *s, int c)
So I curiously looked at both strchr(3) and index(3)...
And I found that both do the following:
The strchr()/index() function locates the first occurrence of c in the string
pointed to by s. The terminating null character is considered to be part of the
string; therefore if c is '\0', the functions locate the terminating '\0'.
So, the manpage is basically a copy & paste.
Besides, I suppose that, because of some obfuscated necessity, the second parameter has type int, but is, in fact, a char. I think I am not wrong, but can anyone explain to me why is it an int, not a char?
If they are both the same, which one is more compatible across versions, and if not, which's the difference?
strchr() is part of the C standard library. index() is a now deprecated POSIX function. The POSIX specification recommends implementing index() as a macro that expands to a call to strchr().
Since index() is deprecated in POSIX and not part of the C standard library, you should use strchr().
The second parameter is of type int because these functions predate function prototypes. See also https://stackoverflow.com/a/5919802/ for more information on this.
It looks like the index() function is an older one that should be replaced by strchr().
See http://www.opengroup.org/onlinepubs/000095399/functions/index.html where they suggest to replace index by strchr and mark index as a legacy function.
Related
I'm creating a header only library and I wanted to check if the user has defined <string.h> so that I can use memcpy. I read online about how libraries like stdio have guard macros, but I couldn't find one for string.h. Any ideas? Or is there a way just to see if memcpy is a function?
You can portably tell if string.h has not been included.
Per 7.24.1 String function conventions, paragraph 1 of the (draft) C11 standard:
The header <string.h> declares one type and several functions, and defines one macro useful for manipulating arrays of character type and other objects treated as arrays of character type. The type is size_t and the macro is NULL ...
If NULL is not defined, then the user could not have included string.h prior to including your header(s).
I see no portable way of definitively determining if string.h has been included.
If you need <string.h>, include it yourself. You can also forward-declare memcpy and use it without including anything:
void* memcpy( void *restrict dest, const void *restrict src, size_t count );
In my current project, I am coding according to the C11 standard (building with gcc -std=c11) and needed something like strnlen (a "safe" version of strlen which returns the length of a 0-terminated string, but only up to a given maximum). So I looked it up (e.g. https://en.cppreference.com/w/c/string/byte/strlen) and it seems the C11 standard mentions such a function, but with the name strnlen_s.
Hence I went with strnlen_s, but this turned out to be undefined when including string.h. On the other hand, strnlen is defined, so my current solution is to use strnlen with a remark that the standard name seems to be strnlen_s but that this is not defined by GCC.
The question is: am I correct to assume that strnlen is the most portable name to use or what could I do for the code to be most portable/standard?
Note: Microsoft (https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/strnlen-strnlen-s) implements both functions with the distinction that strnlen_s checks if the string pointer is NULL and returns 0 in that case while strnlen has no such check.
The question is: am I correct to assume that strnlen is the most portable name to use or what could I do for the code to be most portable/standard?
No, it isn't portable at all. It was never part of C. It is included in POSIX, which doesn't mean much.
I would imagine the reason why the function doesn't exist in the standard, probably because it's superfluous when we already have memchr(str, '\0', max);.
strnlen_s is part of the optional bounds-checking interface in C11 annex K. This whole chapter turned out a huge fiasco and barely any compiler implements it. Microsoft has similar named functions but they are sometimes not compatible. So I would assume that all _s functions are completely non-portable.
So use neither of these, use memchr or strlen.
EDIT
In case you must implement strnlen yourself for some reason, then this is what I'd recommend:
#include <string.h>
size_t strnlength (const char* s, size_t n)
{
const char* found = memchr(s, '\0', n);
return found ? (size_t)(found-s) : n;
}
strnlen_s() is specified in Annex K of the C Standard starting at version C11. This Annex is not widely implemented and even Microsoft's implementation is not fully conformant with the specified version. The semantics are contorted especially regarding error handling. I would recommend not using it.
strnlen() is a simple function specified in POSIX.1-2008 and available on many platforms. It is easy to implement on platforms that do not provide it:
#include <string.h>
size_t strnlen(const char *s, size_t n) {
size_t i;
for (i = 0; i < n && s[i] != '\0'; i++)
continue;
return i;
}
The question is: am I correct to assume that strnlen is the most portable name to use or what could I do for the code to be most portable/standard?
For C, strnlen is OK as the name is not reserved. It is not part of the standard, so OK for you to add.
POSIX reserves str...(), so you might want to use another name.
strnlen_s collides with K.3.7.4.4 The strnlen_s function and has a controversial history that you might not want your code tied into. Avoid naming your function strnlen_s().
I would avoid name coalitions to common libraries with any function one adds with 2 names: the formal less-likely-to-collide-name and macro
size_t nielsen_strnlen(const char *s, size_t maxsize);
#define slength nielsen_strnlen
Or simply go directly with something less likely to collide.
size_t nstrnlen(const char *s, size_t maxsize);
Deeper: OP appears to want to use a popular function that is outside the standard C library (or current version), but might be available when code is ported to other systems. OP wants to provide a use-my-code-if-not-available function.
Careful where you tread.
I would use a macro (or a wrapper function)
#if ON_SYSTEM_WITH_strnlen
#define slength strnlen
#else
#define slength nielsen_strnlen
#endif
... and then use calls to slenth().
Problems comes up when OP's version of code is not exactly like the desired (today and tomorrow) or because it is not standard, various implementations vary - a little bit, on its implementation. To mitigate, consider a macro or function wrapper indirection.
Side issue: Parameter order and a potential new principle to the "original principles" of C.
size_t foo1(const char *s, size_t maxsize);
// arranged such that the size of an array appears before the array.
size_t foo2(size_t maxsize, const char *s);
size_t foo3(size_t maxsize, const char s[maxsize]);
string is the c++ header and string.h is the c header (at least with gcc). strlen_s (afaik) is a Microsoft extension to the C library. You right, strlen would be the more standard. You could also use memchr if you need a byte count. To #Basile's point, if you need count of characters you need something that is UTF-8 aware.
Is it possible to make declaration of variadic function so that it doesn't end with "..."?
Today I learned more about exec from unistd.h but through the day I've seen three (two actually) different declaration of execl:
1) int execl ( const char * path, const char * arg0, ..., (char*)NULL ); was shown to us in school and I imagined I would have to end the function call with a NULL value
2) int execl(const char *path, const char *arg, ... /* (char *) NULL */); is what I've found in the exec(3) man page. That would probably mean I still have to end it with a NULL value, but it is not enforced.
3) int execl(const char *path, const char *arg, ...); is what I found here. This one would probably normally put me to rest with the first one being a simplification for students, the second was a varning and this is the real thing (even though I would probably have normally higher regard for both options one and two.)
But then I found on the same site this declaration:
int execle(const char *path, const char *arg, ..., char * const envp[]);
Same question applies, I was unable to create variadic function not ending in ... with gcc telling me that it's expecting ')' before ',' token pointing to the comma after the three dots.
So finally, is it possible to make variadic functions ending with a NULL characters (execl) and if not, is it possible to make it end with predefined variable (execle)?
I tried to compile with gcc 6.3.1, I also tried --std=c11.
Is it possible to make declaration of variadic function so that it doesn't end with "..."?
Is it possible is a slippery question, but consider these facts:
the standard says that "If a function that accepts a variable number of arguments is defined without a parameter type list that ends with the ellipsis notation, the behavior is undefined" (C2011, 6.9.1/8)
Perhaps that answers the question already, but if you choose to mince words and focus on function declarations that are not definitions, then
a function definition is also a declaration
the C language standard requires all declarations of the same function to be "compatible" (else program behavior is undefined) (C2011 6.7/4)
two function declarations with mismatched parameter lists are not compatible (C2011, 6.2.7/3)
Thus, if you declare a variadic function that in fact is also defined, and that function's parameter list does not end with ..., then the program's behavior is undefined.
The documentation you've been reading for execle() and execl() is written to express and discuss those functions' expectations, but to the extent that it seems to present variadic function declarations in which the last element of the parameter list is not ..., those are not actually valid C function declarations.
So finally, is it possible to make variadic functions ending with a NULL characters (execl) and if not, is it possible to make it end with predefined variable (execle)?
It is not possible to describe such calling conventions via conforming C declarations. Variadic functions can have such expectations, and can enforce them at runtime, but they can be enforced at compile time only by a compiler that relies on special knowledge of the functions involved, or on C language extensions that allow such constraints to be described.
The declaration of a variadic function can only specify the required arguments, and the compiler can enforce their types. The variable-length part never has any type checking done. And the variable-length part is always at the end. The declaration for execle() is not meant as an actual C declaration, but just to describe to the programmer how he should construct the arguments.
It's not possible to enforce that the last argument to execl() is NULL. Variadic functions don't know how many arguments were supplied, they determine it from the values of the arguments. printf() assumes that it has enough arguments to fill in all the operators in the format string, and execl() iterates through the arguments until it finds NULL (execle() is similar, but it reads one additional argument to get envp). If you don't end with NULL, it will just keep going, reading garbage and causing undefined behavior.
The declaration you see is the one in the man pages of execl. The declaration for execle in glib is the following: int execle (const char *path, const char *arg, ...). The implementation assumes the last argument is a char**, and uses it for envp. I don't think you can enforce such a rule in C.
How do I can display a string value without using the standard libraries in C language? please see the following code:
//without using the standard libraries that other created it
int main() {
string str = "Hello";
//How do I can display str value without using the standard libraries that other created it?
}
Here's how you can do it :
// Declare the prototype for the write() function,
// with unspecified parameters because why not.
extern long write();
int main(void) {
char const *str = "Hello";
// Retrieve the length
unsigned long size = 0;
while(str[size])
++size;
// Write to stdout (fd 1)
write(1, str, size);
return 0;
}
Live on Coliru.
Of course, it's as non-portable as it gets, and will probably fail to link or trigger UB on the majority of systems other than the one I pulled the declaration from (it's a Linux system call, declared in unistd.h which I retrieved from Coliru). But then, that's why we have the standard library in the first place.
Quite simply, you can't, at least not if you want your code to be at all portable.
Almost certainly there's some way to perform output in C code without using the standard library. But the way to do that will vary widely from one system to another. A solution that works on UNIX systems, for example, almost certainly won't work on Windows, and vice versa -- unless that solution uses the C standard library, which is customized for each system.
That's why the standard library exists. And on freestanding (embedded) implementations that don't support the standard library, you have to write system-specific code to do any I/O.
If you want to know how to do I/O on a particular system without using the standard library, I suggest posting a new question.
int main() {
string str = "Hello";
}
int main() is better written as int main(void).
There is no type string in C. What you probably want here is either
const char *str = "Hello";
or
char str[] = "Hello";
A "string" in C is by definition "a contiguous sequence of characters terminated by and including the first null character". It's a data format, not a data type. (C++ has a type std::string, but you're asking about C, not C++ -- and in C++ std::string is itself defined by the C++ standard library.)
The comp.lang.c FAQ is an excellent resource.
I seem to be able to compile code that calls wsprintf with the MinGW gcc if I have these includes (in this order):
#include <stdarg.h>
#include <wingdi.h>
#include <winuser.h>
But I feel like there might be some "cleaner" way to do this. Perhaps with only a single header inclusion. I arrived at this list by searching header files for missing symbols and then including headers one-by-one.
Include <Windows.h>
Do you mean swprintf()?
swprintf() is described in the C99 standard. You need <wchar.h>.
If wsprintf does the same as swprintf you may want to consider using a standard function instead.
7.24.2.3 The swprintf function
Synopsis
[#1]
#include <wchar.h>
int swprintf(wchar_t * restrict s,
size_t n,
const wchar_t * restrict format, ...);
Description
[#2] The swprintf function is equivalent to fwprintf, except
that the argument s specifies an array of wide characters
into which the generated output is to be written, rather
than written to a stream. No more than n wide characters
are written, including a terminating null wide character,
which is always added (unless n is zero).
Do you mean the standard function swprintf? In that case you should include wchar.h.