|
how do we use char *function(), and does it returns character, like int function() returns an integer ?
|
|
|
|
|
Tarun Jha wrote: how do we use char *function(), and does it returns character... It returns a pointer to a character.
However, C is not a strong-typed language so you can coerce that into many things. Pointers are a prime example of C being known for giving you just enough rope to hang yourself. Just sayin...
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
There is no simple method in C to return a string from a function.
Possible methods are:
1. Passing a char* pointer to the function and the function fills the passed buffer. In such cases the size of the buffer should be also passed and the return value indicates failure (usually -1) or success (usually length of copied string):
int input(char *buf, int buf_size)
{
char local_buf[100] = "";
fgets(local_buf, sizeof(local_buf), stdin);
int len = strlen(local_buf);
if (buf_size <= len)
return -1;
strcpy(buf, local_buf);
return len;
}
2. Letting the function allocate a buffer. The calling function must free the buffer when no longer used:
char *input()
{
char local_buf[100] = "";
fgets(local_buf, sizeof(local_buf), stdin);
return strdup(local_buf);
}
char *input_str;
input_str = input();
free(input_str);
However, in your case there is no need for an own function because it is already provided by the standard C library: fgets - C++ Reference[^].
|
|
|
|
|
You can't do this. Because array c is released when input() function execute completed. Maybe you can used "static" key word to prevent array c to released or pass a buffer to input() function as parameter.
|
|
|
|
|
As per your last post lets fix my code from it into a function .. which is what I assume you are trying to do
int StringInput (char* name, int namemax)
{
int c;
int namelen = 0; if (name && namemax > 1) { do {
c = getc(stdin); name[namelen++] = (char) c; } while (c !=EOF && c != '\n' && namelen < namemax-1); temp.name[namelen-1] = '\0'; }
return(namelen); }
/
int main(void)
{
char name[100];
int len = StringInput(&name[0], sizeof(name));
StringInput(&name[0], sizeof(name));
}
Now if this is for uni or commercial then you probably want this form ... An excercise for you is to understand why and how to do it
int StringInput (const char* name, const int namemax, const FILE* source)
In vino veritas
modified 3-Jan-18 21:27pm.
|
|
|
|
|
Quote: if (name && namemax > 1) .
why name is there when it is a char, and how can it be > 1?? And it works fine if i remove it.
|
|
|
|
|
Tarun Jha wrote: Quote: if (name && namemax > 1) .
why name is there when it is a char, and how can it be > 1?? And it works fine if i remove it.
You could rewrite it to be:
if (name != NULL && namemax > 1))
that means that name points to some space in memory and the length of this "space" (character array) is > 1.
And "it works fine if i remove it" only means that name != NULL and namemax > 1
|
|
|
|
|
|
Tarun Jha wrote: And it works fine if i remove it. It does not work fine if you remove it because you now have a rather hidden bug in your code. Get hold of a good book on C (as I have repeatedly suggested) and issues like this will become clear.
|
|
|
|
|
i bought k&r but it's a bit difficult for me to understand.
|
|
|
|
|
K&R is probably the easiest introduction to C. If you find it hard then you need to read it through quite a few times.
|
|
|
|
|
i will do it as many times as needed until i get the concepts.
|
|
|
|
|
Again Richard MacCutchan is correct so let me explain my code
name is a "pointer to a char" NOT a char
So this line
if (name && namemax > 1)
Is a shortcut of writing
if ( (name != 0) && (namemax > 1) )
writing
if (anything)
Basically checks if the thing called "anything" is not zero its a shortcut
So what the line it is checking is the pointer called name is not 0 (or null which is an invalid pointer)
the space for the buffer name is greater than 1 .. why well the code specifically
makes an '\0' terminated C string so it needs a minimum buffer size of 1 to hold the '\0'
So name == 0 or namemax == 0 would bug the code so they are specifically handled.
So the line is a specific safety to make sure you could NEVER bug the routine doing
either the function will simply return 0 which is correct it read no character data.
There are a couple of other possible background bugs and program hints which was in
my hint to change the interface.
1.) The use of "stdin" could be possibly problematic in some esoteric systems .. you
don't know it's actually a device there might be no keyboard etc on the system. As such
bringing it in thru the interface pass that responsibility out to the caller code.
2.) We don't ever change name or namemax internally so placing a const in front of them
makes it clear that is the case and also allows the optimizer to really go to work. So
it's not a bug fix but a help to the compiler and anyone using the code.
So that is as robust to function input error as I can make your function.
You are left with two possible errors outside my control passing in a pointer to some
wrong place and passing in a wrong maximum buffer size. I would have to be a mind reader
to be able to deal with those but I have dealt with all the obvious possible errors.
In vino veritas
modified 4-Jan-18 21:08pm.
|
|
|
|
|
Thank you for your elaborated explanation i was able to understand and learn many new things.
|
|
|
|
|
I have been practicing structures and function and while making a program that does not accept '\n' and EOF as input. Below is the program, it takes input but the compiler does not shows any error.
#include <stdio.h>
#include <string.h>
typedef struct
{
char name[100];
int goals;
}match;
match check();
int main()
{
int log;
match team;
scanf("%d", &log);
printf("Enter goals:\n");
scanf("%d", team.goals);
fflush(stdin);
team = check();
printf("Name: %s\t\tGoals: %d\n", team.name, team.goals);
return 0;
}
match check()
{
int c;
match temp;
gets(temp.name);
if((c=temp.name[0])==EOF && c == '\n')
{
printf("Invalid entry!");
check(temp);
}
return(temp);
}
|
|
|
|
|
Tarun Jha wrote:
if((c=temp.name[0])==EOF && c == '\n') I'm not sure how a character retrieved from gets() could ever be equal to -1, but that issue aside, I do not believe that the variable c can be equal to both EOF (or any other value) and \n at the same time.
Another issue with gets() is buffer overflow.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
modified 3-Jan-18 11:11am.
|
|
|
|
|
But in K&R it's && not ||
|
|
|
|
|
|
Read what David Crow said and then realize name is a char array .. that is 8 bits
You move it to an int with c=temp.name[0] but that will be a truncated 8 bit value.
That is comparing it to EOF which is an int value will always fail.
That is what Richard is trying to tell you. You probably want name as an array of int or wide chars.
So you have 2 problems and which have both been identified and you need to deal with both.
I am just making sure you realize BOTH comments are valid and address different issues.
In vino veritas
|
|
|
|
|
i searched on net but didn't got the concept of how it should be corrected.
can you tell me how to correct it ?
modified 3-Jan-18 9:47am.
|
|
|
|
|
Tarun Jha wrote: i searched on net but didn't got the concept... So what if the "net" ceased to exist one day? Some things you just have to learn by doing, not by searching.
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|
|
yes, i tried it many times but am unable to do it correctly. That's why i'am asking for correct answer.
|
|
|
|
|
Tarun Jha wrote: That's why i'am asking for correct answer. Did you try replacing logical AND with OR? Did you try changing c to be a char instead of an int ? Did you set a breakpoint on the if() test to see what the value of name[0] is? As the documentation states, it is neither EOF nor \n .
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
modified 3-Jan-18 11:52am.
|
|
|
|
|
yes i did, and it still does'nt works.
#include <stdio.h>
#include <string.h>
typedef struct
{
char name[100];
int goals;
}match;
match check();
int main()
{
match team, temp;
printf("Enter goals:\n");
scanf("%d", &team.goals);
fflush(stdin);
temp = check();
printf("Name: %s\t\tGoals: %d\n", temp.name, team.goals);
return 0;
}
match check()
{
char c;
match temp;
printf("Name: \n");
gets(temp.name);
if((c=temp.name[0])==EOF || c == '\n')
{
printf("Invalid entry!");
check(temp);
}
return(temp);
}
|
|
|
|
|
Tarun Jha wrote: check(temp); How does this compile?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"You can easily judge the character of a man by how he treats those who can do nothing for him." - James D. Miles
|
|
|
|