开发者

this code, its work fine and return what i want, but its hangs before print it?

开发者 https://www.devze.com 2022-12-25 01:13 出处:网络
I make this program :: #include<stdio.h> char *raw_input(char *msg); main() { char *s; *s = *raw_input(\"Message Here Is: \");

I make this program ::

#include<stdio.h>

char *raw_input(char *msg);

main() {
char *s;
*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);
}

char *raw_input(char *msg){
char *d;
    printf("%s", msg);
    scanf("%s",&d);
return d;
}

What this do is, it开发者_JS百科 print my message and scan for input from the user, then print it,, but whats the problem in print the input from the user ???

Update::

I need the raw_input func. call be like this without any extra

*s = *raw_input("Message Here");

I dont want to use this ::

raw_input("Message Here Is: ", d);
....

Just want to return the string that the user will enter .

Update2::

from jamesdlin Answer( Thank You ),,Now its clear to my that's my problem was in how to return an allocated string in this :)

#include<stdio.h>
#define buffer 128

char *raw_input(char *msg);

main() {
char *s;
s = raw_input("Message Here Is: ");
printf("%s\n",s);
}

char *raw_input(char *msg){
char *d;
    printf("%s", msg);
    fflush(stdout);
    fgets(d, buffer, stdin); ## In this there is a problem
return d;
}

now when i start this program its print the message and then just exit(end)the program without taking any word from the user ???


You don't allocate memory for d, so using it in scanf leads to undefined behaviour.

Actually, it's even worse than that: you pass the address of d to scanf, which is then filled with the integer read from console. In effect, you initialize a pointer with an integer value, so the pointer points to somewhere out in the jungle. Thus dereferencing it is undefined behaviour. [Update]: even this is not all: as @Heath pointed out below, this in fact allows you to corrupt your call stack by entering a sufficiently long input on the console :-((( [/Update]

Not to mention that you are trying to return a local variable from your function, which is destroyed as soon as it gets out of scope. This should work better:

void raw_input(char *msg, char *d);

main() {
    char d[128];

    raw_input("Message Here Is: ", d);
    printf("Return Done..");
    printf(d);
}

void raw_input(char *msg, char *d){
    printf("%s", msg);
    scanf("%s", d);
}

Fair enough, this does not prevent buffer overflow... but it is enough to ilustrate my point.

Update: so you want to return an allocated string (i.e. a char* pointer) from raw_input() in any case. AFAIK you have 3 choices:

  • return a pointer passed in by the caller as a parameter (a slight extension of my example above): this is the one I would prefer. However, this requires an extra function parameter (in fact 2, since we should also pass in the length of the buffer in a proper solution to avoid buffer overflows). So if you absolutely need to stick to the function signature shown above, this isn't an option.
  • return a pointer to a static / global buffer visible to both caller and callee: this is a variation of the above, to avoid modifying the function signature. The downside is that the code is more difficult to understand and maintain - you don't know that the function modifies a static / global variable without actually looking at its implementation. This in turn also makes unit testing more difficult.
  • return a pointer to a buffer allocated inside the function - although technically possible, this is the worst option, since you effectively pass on the ownership of the buffer; in other words, the caller must remember to free the buffer returned. In a simple program like the one you showed above, this may not seem like a big issue, but in a big program, that buffer may be passed around to far away places within the app, so there is a high risk that noone frees it in the end, thus leaking memory.


The pointer d in the function is uninitialized. scanf would be filling up arbitrary memory. Instead, you need to pass a buffer (character array) for it to fill, and the buffer has to be defined in main, otherwise it'll be destroyed before you can return it (unless you do dynamic allocation, but that's another story).


#include<stdio.h>

char *raw_input(char *msg);

int main() {
    char *s;
    s = raw_input("Message Here Is: ");
    printf("Return Done..");
    printf("%s", s);
    free(s);
    return 0;
}

char *raw_input(char *msg){
    char *d;
        d = malloc(20)
        if(d==0) return 0;
        printf("%s", msg);
        scanf("%19s", d);
    return d;
}

Try this, should work. The other answers pointed your errors out, as I can see... I was to slow ;)

EDIT: Ok, found an error... fixed it ;)

EDIT2: Max suggested a struct was possible, here is some code:

#include<stdio.h>

struct mystring{
    char str[20];
};

struct mystring raw_input(char *msg);

int main() {
    struct mystring input;
    input = raw_input("Message Here Is: ");
    printf("Return Done..");
    printf("%s", input.str);
    return 0;
}

struct mystring raw_input(char *msg){
    struct mystring input;
        printf("%s", msg);
        scanf("%19s", input.str);
    return input;
}


As mentioned, you aren't allocating memory for use with scanf. But never ever use scanf; it's hard to use correctly and to avoid buffer overflows. Use fgets.

From the comp.lang.c FAQ: Why does everyone say not to use scanf? What should I use instead?

Also, while unrelated to your problem, this bit of code is dangerous:

*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf(s);

You are passing user-input directly to printf as a format strings, so this is susceptible to format string attacks if the printed string happens to include % characters. Better:

*s = *raw_input("Message Here Is: ");
printf("Return Done..");
printf("%s\n", s);

Also, you might want some newlines when you print. Also:

*s = *raw_input("Message Here Is: ");

won't work because s doesn't point to anything, so you're dereferencing a garbage pointer. Assuming that you fix raw_input to return an allocated string, it should be:

s = raw_input("Message Here Is: ");

Lastly (also unrelated to your problem):

char *raw_input(char *msg){
    char *d;
    printf("%s", msg);
    scanf("%s",&d);
    return d;
}

You should call fflush(stdout) after printing the prompt. See My program's prompts and intermediate output don't always show up on the screen, especially when I pipe the output through another program.


Try this experiment:

#include<stdio.h>

char *raw_input(char *msg);

main() {
    char *s;
    s = raw_input("Message Here Is: ");
    printf("Return Done..");
    printf(s);
}

char *raw_input(char *msg)
{
    int value = 0;
    char *d;
    printf("%s", msg);
    scanf("%s",&d);

    if (value)
        printf("value has become %08X\n", value);
    return d;
}

Perform several experiements with input messages as long as: 3, 4, 5, 7, 8, 9, 11, 12, 13, etc. characters long. See what the result is for the integer variable value. You will see that due to your misuse of scanf() by passing the address of d, you are allowing scanf() to destroy local variables of your function, including the return address.

And that gets us back to the name of this web site.


You can not return a pointer of a variable that has been created inside the function. The variable d is not valid anymore in the main function.

try this: 1. create the variable d in the main function 2. and pass it to the raw_input function

void raw_input(char *msg, char *d)
0

精彩评论

暂无评论...
验证码 换一张
取 消