putchar(char) writes a character to standard output and is normally provided by stdio.h.
How do I write a character to standard output without using stdio.h or any other standard library file (that is: no #include:s allowed)?
Or phrased different, how do I implement my own putchar(char) with zero #include statements?
This is what I want to achieve:
/* NOTE: No #include:s allowed! :-) */
void putchar(char c) {
/*
* Correct answer to this question == Code that implements putchar(char).
* Please note: no #include:s allowed. Not even a single one :-)
*/
}
int main() {
putchar('H');
putchar('i');
putchar('!');
putchar('\n');
return 0;
}
Clarifications:
Please note: No #include:s allowed. Not even a single one :-)
The solution does not have to be portable (inline assembler is hence OK), but it must compile with gcc under MacOS X.
Definition of correct answer:
A working putchar(char c) function. Nothing more, nothing less :-)
On a POSIX system, such as Linux or OSX, you could use the write system call:
/*
#include <unistd.h>
#include <string.h>
*/
int main(int argc, char *argv[])
{
char str[] = "Hello world\n";
/* Possible warnings will be encountered here, about implicit declaration
* of `write` and `strlen`
*/
write(1, str, strlen(str));
/* `1` is the standard output file descriptor, a.k.a. `STDOUT_FILENO` */
return 0;
}
On Windows there are similar functions. You probably have to open the console with OpenFile and then use WriteFile.
void putchar(char c) {
extern long write(int, const char *, unsigned long);
(void) write(1, &c, 1);
}
There is no platform-independent way of doing this.
Of course, on any specified platform, you can trivially achieve this by reimplementing/copy-and-pasting the implementation of stdio.h (and anything that this in turn relies on). But this won't be portable. Nor will it be useful.
Since providing a full solutions is probably unsporting, this is the next best thing... which is the source-code for Apple's implementation - which is open source.
I think reducing this to a minimum case is an exercise for the OP. Apple have even kindly provided an XCode project file.
Related
I have used strlen() function from the string.h library without including the header which I want to include from the header file which is initially implemented, because I am writing my own implementation of strcpy(),if I include the header it says it's multiple definitions of strcpy ().
So how do I include only a particular definition from the header file.
Do I need to use extern keyword?
#include <stdio.h>
#include <stdlib.h>
#include "exercise 5.5.h"
int main() {
char *s = "hello";
char *t = "helli";
int n = 3;
if (n > strlen(t))
printf("\nsorry the value of n is greater than the size of t");
else {
S = strncpy(s, t, n);
printf("\nther is %d", x);
}
}
The header has definition of strncpy
Terminal trace
exercise. 5.5_main.c:10:7: incompatible implicit declaration of built-in function "strien
exercise 5.5 main.c:10:7: note: include <string.h> or provide a declaration of 'strlen
I don't want to include string.h but how do I explicitly provide definition of strlen
Header
char* strncat(char *s, char *t, int n);
char* strncpy(char *s, char *t, int n);
int strncmp(char *s,char *t, int n);
Reimplementing a standard library function like strcpy can be tricky. Since it's a standard library function, its name is in a sense "reserved" -- you're not supposed to use it yourself. (It's not quite as strongly reserved as is a keyword like switch, but it's still generally a bad idea to try to write a function named strcpy -- not to mention the fact that it's usually perfectly unnecessary!)
In answer to your explicit question, no, there's no way to "selectively include" just your own selection of the declarations in a system header file such as <string.h>.
If for some reason you need to write your own version of strcpy, you have several choices, depending on circumstances.
Rename your own function. For example, call it my_strcpy. (This is the usual approach.)
Make sure the definition of your function is perfectly correct, and matches the declaration in the standard header file exactly. For example, if you have strcpy(char *dst, char *src) {...} or char *strcpy(char *dst, char *src) {...}, those are both wrong -- it needs to be char *strcpy(char *dst, const char *src) {...}.
Don't use the standard strlen function, either, meaning that you don't have to do a #include <string.h> at all. If you need it, write your own version of strlen, too. (This is often the requirement if the reason you're writing your own strcpy is as a teaching exercise: often the assignment says "You may not use any other functions from the standard library.")
Instead of doing a #include <string.h> because you're calling strlen, provide your own prototype for it at the top of your file: extern size_t strlen(const char *);. (This is generally an extremely bad idea for several reasons, and is not a step to be taken except under extreme circumstances and when you know exactly what you're doing.)
It may also be significant to note whether the "redefinition" error you're getting is coming from the compiler or the linker. If it's a compile-time error such as "conflicting types for 'strcpy'", it indicates you probably need to pay attention to point 2 just above. But if it's a link-time error like "ld: duplicate symbol '_strcpy'" there may not be anything you can do about it, and you'll have to fall back on point 1.
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'm learning the C language,has written the following code:
#include <stdio.h>
void main()
{
char ch='a';
printf("%c\n", ch);
}
Then I use GCC to compile the code,but i get a mistake:
return type of 'main' is not 'int' [-Wmain-return-type]
I didn't use any data type int,what's wrong?
As the compiler is telling you, main() must return int
int main(void)
{
return 0;
}
the return value being the exit code of the program.
In this case you need to use
#include <...>
int main(){
//code
return 0; //or return any_integer;
}
If your program returns nothing the system will never know was the run successful or there were some errors.
Use:
int main(void) { /* ... */ }
for the definition of main function with no argument. Note that int main() { /* ... */ } is also valid but the former definition is preferred.
Get into the habit of using:
int main( int argc, char* argv[] ){
// your code
return 0;
}
argc is the number of arguments being passed to the program.
argv is the array of arguments in string from.
The error mean, the main() should return int. Make main() as int type and return an valid exit condition integer, usually termination is return 0. Please refer to this previous SO answer
Okay, so everyone is speaking about running C programs UNDER an Operating system. This is totally true:
From the standard point, since the main should return int.
From the operating systems point, since the int returning from the main is mapped to the exit code of the program.
But no one is speaking of other uncommon conditions that of course can happen when implementing a C program: For example, a C binary that is not being run under any operating system, a C binary that does not return nothing from its main because there is no one to receive or interpret the value, a C binary that actually is the Operating System or a C binary that controls an embedded system where its main function is to synchronize its components inside an infinite loop, waiting for petition (and by definition never returning). The previous examples are more or less equivalent.
In those cases, even if the compiler complains it makes sense to define your main like:
void main()
{
...
}
You have to take warnings seriously, but it is more important to understand what are you actually doing. That is the main caveats of C: With great power comes great responsibility.
If you are under those circumstances, the definition of main does not matter very much since there is no one to call it nor no one to receive its exit value.
Anyway, there is no real concern about the main signature in those circumstances, and optimization does not seem like an improved characteristic of those C programs if they are defined as void main() or as int main(int argc, char* argv[]).
So, conclusion:
When expecting to be run under an operating system (I think this would be true most of the time): Use the standard definition of main int main(int argc, char* argv[]). The warning of gcc was considered for these circumstances.
When you do not have an operating system: Do as you please, it does not matter, except for the fact of having an annoying warning that does not make sense in those exact circumstances.
This question already has answers here:
Why does omitting explicit 'int' type for a parameter fail to compile in gcc sometimes?
(2 answers)
Closed 8 years ago.
I've read some, to me, peculiar C-code while studying some examples in the book The Unix Programming Environment (1983).
As a curiosity I wanted to find out more about the, let's call it "style". The point of interest here is the line just below int main(argc, argv)
#include <stdio.h>
int main(argc, argv)
char *argv[];
{
printf("%s\n", argv[0]);
return 0;
}
In my investigation I've found that compiling the above code with the flags -Wall -pedantic -ansi works without any warnings, and replacing -ansi with the more recent -std=c99 (or c11, with gcc and cc) only warns about argc defaulting to int.
I perused the old C89 standard trying to find references to this particular way of writing
but didn't find anything on my own so I defer to the greater knowledge of the collective.
Hence the question, from when does this esoteric writing stem and possibly why is it still allowed (legacy reasons?)
The old way to do things was to have functions without prototypes. Functions return int by default, and since the function parameter types are unknown at the call site, you better get it right. This frees you from having to maintain header files, but for various reasons, it is no longer recommended.
// In func.c
// Default to int return
func(x, y)
int x;
int y;
{
return x + y;
}
// In main.c
main(argc, argv)
int argc;
char **argv;
{
int result = func(2, 3);
}
This causes problems if you get the function parameter types wrong.
int result = func(2.0, 3,0); // Wrong, but no compiler error or warning
It was normal to call functions without including the relevant header file. But you need to declare the function return type.
// This is NOT a function prototype, it just declares the return type.
double sin();
double one = sin(3.14); // Correct
double zero = sin(0); // WRONG
double zero = sin(0.0); // Correct
Old style functions are still allowed by the standard, except the default return type is gone. This allows you to compile old programs. For new programs, the -Wmissing-prototypes option in GCC helps you to avoid using the old style by accident.
int func(); // Old-style, can take any number of arguments.
int func(void); // New-style, takes no arguments, is a function prototype.
This is good old fashioned K&R C.
Everything is by default an integer, and you define the actual types of parameters in functions, not in the prototype, but in a separate declaration list. It made writing integer-only code easier, but made debugging function calls a nightmare.
Here's a function written in both styles.
int myFunc(const char *from, char *to, int len); // Ah that feels right, doesn't it
int myFunc(const char *from, char *to, int len){} // And here's the definition
myKRFunc(); /* Okay, that's a declaration */
myKRFunc(from, to, len) /* Yep, you just write the parameter names here */
char *from, *to; /* And you can write normal declarations, len defaults to an int */
{}
I wanted to explain why debugging function calls without prototypes was harder, but Dietrich covers it in his answer well.
This is the original K&R style C. It's still legal, because why not? Backwards compatibility lets people move forward in small steps. That's the pain of any popular evolving system.
This is based on the old "standard", so I wouldn't worry too much about it. I definitely don't recommend programming in that style, but it's useful to know it exists in case you encounter more legacy code.
Edit 3: For the code itself all together check the first answer or the end of this post.
As stated in the title I'm trying to find a way to tell if an optional argument was passed to a function or not. What I'm trying to do is something like how almost all dynamic languages handle their substring function. Below is mine currently, but it doesn't work since I don't know how to tell if/when the thing is used.
char *substring(char *string,unsigned int start, ...){
va_list args;
int unsigned i=0;
long end=-1;
long long length=strlen(string);
va_start(args,start);
end=va_arg(args,int);
va_end(args);
if(end==-1){
end=length;
}
char *to_string=malloc(end);
strncpy(to_string,string+start,end);
return to_string;
}
Basically I want to still be able to not include the length of the string I want back and just have it go to the end of the string. But I cannot seem to find a way to do this. Since there's also no way to know the number of arguments passed in C, that took away my first thought of this.
Edit:
new way of doing it here's the current code.
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
#define substring_defarg_2 (0)
char *substring(char *string,unsigned int start, int end){
int unsigned i=0;
int num=0;
long long length=strlen(string);
if(end==0){
end=length;
}
char *to_string=malloc(length);
strncpy(to_string,string+start,end);
return to_string;
}
and then in a file I call test.c to see if it works.
#include "functions.c"
int main(void){
printf("str:%s",substring("hello world",3,2));
printf("\nstr2:%s\n",substring("hello world",3));
return 0;
}
functions.c has an include for functions.h which includes everything that is ever needed. Here's the clang output(since clang seems to usually give a bit more detail.
In file included from ./p99/p99.h:1307:
./p99/p99_generic.h:68:16: warning: '__error__' attribute ignored
__attribute__((__error__("Invalid choice in type generic expression")))
^
test.c:4:26: error: called object type 'int' is not a function or function
pointer
printf("\nstr2:%s\n",substring("hello world",3));
^~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from test.c:1:
In file included from ./functions.c:34:
In file included from ./functions.h:50:
./string.c:77:24: note: instantiated from:
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
GCC just says the object is not a function
Edit 2: Note that setting it to -1 doesn't change it either, it still throws the same thing. The compile options I'm using are as follows.
gcc -std=c99 -c test.c -o test -lm -Wall
Clang is the same thing(whether or not it works with it is another question.
ANSWER HERE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/types.h>
#include "p99/p99.h"
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
#define substring_defarg_2() (-1)
char *substring(char *string, size_t start, size_t len) {
size_t length = strlen(string);
if(len == SIZE_MAX){
len = length - start;
}
char *to_string = malloc(len + 1);
memcpy(to_string, string+start, len);
to_string[len] = '\0';
return to_string;
}
You will need p99 from there. It is by the selected answer. Just drop into your source directory and you should be OK. Also to summarize his answer on the license. You're able to use it however you want, but you cannot fork it basically. So for this purpose you're free to use it and the string function in any project whether proprietary or open source.
The only thing I ask is that you at least give a link back to this thread so that others who happen upon it can learn of stack overflow, as that's how I do my comments for things I've gotten help with on here.
In C, there's no such thing as an optional argument. The common idiom for situations like this is to either have two functions; substr(char *, size_t start, size_t end) and substr_f(char *, size_t start) or to have a single function where end, if given a special value, will take on a special meaning (such as in this case, possibly any number smaller than start, or simply 0).
When using varargs, you need to either use a sentinel value (such as NULL) at the end of the argument list, or pass in as an earlier argument the argc (argument count).
C has a very low amount of runtime introspection, which is a feature, not a bug.
Edit: On a related note, the correct type to use for string lengths and offsets in C is size_t. It is the only integer type that is guaranteed to be both large enough to address any character in any string, and guaranteed to be small enough to not be wasting space if stored.
Note too that it is unsigned.
Other than common belief functions with optional arguments can be implemented in C, but va_arg functions are not the right tool for such a thing. It can be implemented through va_arg macros, since there are ways to capture the number of arguments that a function receives. The whole thing is a bit tedious to explain and to implement, but you can use P99 for immediate use.
You'd have to change your function signature to something like
char *substring(char *string, unsigned int start, int end);
and invent a special code for end if it is omitted at the call side, say -1. Then with P99 you can do
#include "p99.h"
#define substring(...) P99_CALL_DEFARG(substring, 3, __VA_ARGS__)
#define substring_defarg_2() (-1)
where you see that you declare a macro that "overloads" your function (yes this is possible, common C library implementations use this all the time) and provide the replacement with the knowledge about the number of arguments your function receives (3 in this case). For each argument for which you want to have a default value you'd then declare the second type of macro with the _defarg_N suffix, N starting at 0.
The declaration of such macros is not very pretty, but tells at least as much what is going on as the interface of a va_arg function would. The gain is on the caller ("user") side. There you now can do things like
substring("Hello", 2);
substring("Holla", 2, 2);
to your liking.
(You'd need a compiler that implements C99 for all of this.)
Edit: You can even go further than that if you don't want to implement that convention for end but want to have two distinct functions, instead. You'd implement the two functions:
char *substring2(char *string, unsigned int start);
char *substring3(char *string, unsigned int start, unsigned int end);
and then define the macro as
#define substring(...) \
P99_IF_LT(P99_NARG(__VA_ARGS__, 3)) \
(substring2(__VA_ARGS__)) \
(substring3(__VA_ARGS__))
this would then ensure that the preprocessor chooses the appropriate function call by looking at the number of arguments it receives.
Edit2: Here a better suited version of a substring function:
use the types that are semantically correct for length and stuff like
that
the third parameter seems to be a length for you and not the end of the string, name it accordingly
strncpy is almost never the correct function to chose, there are situations where it doesn't write the terminating '\0' character. When you know the size of a string use memcpy.
char *substring(char *string, size_t start, size_t len) {
size_t length = strlen(string);
if(len == SIZE_MAX){
len = length - start;
}
char *to_string = malloc(len + 1);
memcpy(to_string, string+start, len);
to_string[len] = '\0';
return to_string;
}
Unfortunately, you cannot use va_arg like that:
Notice also that va_arg does not determine either whether the retrieved argument is the last argument passed to the function (or even if it is an element past the end of that list). The function should be designed in such a way that the amount of parameters can be inferred in some way by the values of either the named parameters or the additional arguments already read.
A common "workaround" is to give the other "overload" a nice mnemonic name, such as right_substr. It will not look as fancy, but it will certainly run faster.
If duplicating implementation is your concern, you could implement left_substr, substring, and right_substr as wrappers to a hidden function that takes start and length as signed integers, and interprets negative numbers as missing parameters. It is probably not a good idea to use this "convention" in your public interface, but it would probably work fine in a private implementation.
In standard C, when using variable argument prototypes (...), there is no way to tell directly how many arguments are being passed.
Behind the scenes, functions like printf() etc assume the number of arguments based on the format string.
Other functions that take, say, a variable number of pointers, expect the list to be terminated with a NULL.
Consider using one of these techniques.