3

I am trying to get a full sentence eg. "This is a sentence." to be stored in the global variable string named 'global'. It will then print out the sentence back out. However after entering my input, I can only get the first word of the sentence printed (This). Anyone got any ideas?

#include <string.h>

char** global;

int main () {

    printf("Please Enter Text: \n");
    scanf("%s", &global);

    printf("%s", &global);


    return 0;
}
2
  • Ampersand(&) should not be there in printf Commented Oct 12, 2013 at 13:14
  • 1
    @ShashankKadne: without the &, global is still a pointer to a char pointer. If it points at valid data structures, then *global would give a char * that could be printed with %s. Commented Oct 12, 2013 at 14:24

3 Answers 3

4

The char** global should be char* global only.

& with printf is not required.

You need to use fgets(var_name,no_of_chars,FILE*) in place of scanf.

fgets(global,100,stdin); //where global is char global[100]; 

Example :

Use of gets is more serious then i was thinking. So it's no longer recommended.

A Better one

char global[100];    
int main () {
    printf("Please Enter Text: \n");
    if(fgets(global,50,stdin)) //It will take Maximum 50 chars. So no buffer overflow. 
    fputs(global,stdout);
    return 0;
}
Sign up to request clarification or add additional context in comments.

8 Comments

if i enter multiple lines as input, the (unknown code) will only print first line. can do i fix that?
@NewFile: that is a new question, unrelated to the current one.
-1: Dammit: Never, but never, recommend gets(). It is lethal. It is also no longer standard C (it was removed from the C11 standard). Always use either fgets() or (on a POSIX system) getline() or a similar function. You do have to deal with the newline with fgets(); that is a nuisance (and it might be a reason to write your own cover function for fgets() that removes it and, since it has the information, reports on the length of the string read). But don't ever use gets(), not even in toy code.
There's a secondary problem; you've only implicitly covered the fact that char **global; (or char *global;) is a null pointer; space must be allocated. Your final 'if size is unknown' code has & that should not be present, and is misguided. If you don't know how much space global points at, you have to do stuff like if (global != 0 && (len = strlen(global) + 1) > 1) { if (fgets(global, len, stdin) != 0) fputs(global, stdout); } using the length of the string that global points to as the (presumably) safe length. Anything longer could be problematic.
Downvote rescinded. The answer has been improved considerably since I downvoted it (and improvement was the objective of the downvote).
|
3

Your variable char **global; is a disaster zone. It is a null pointer. It must be made to point to some valid data before it can be used. It is a double pointer, in fact, so you have to make space available like this:

char array[1000];
char *pointer = array;
char **global = &pointer;

Now you could safely use global[0].

Inside the function, you pass &global to scanf(); that is a char ***. Being a 'Three-Star Programmer' is not a good thing, especially when you do it by accident and not by design.

You include the header <string.h> but don't use any of its functions. You do use functions from <stdio.h> and you don't include that. Technically, you invoke undefined behaviour by using the variadic functions printf() and scanf() without a function prototype in scope. The compiler is entitled to be told about functions that take a variable number of arguments (that's what 'variadic' means), and is entitled to miscompile code where it is not told that the function is variadic.

Assuming you really do need a global variable at all (they're generally not a good idea and you should avoid using them as much as possible), then you could reasonably write:

#include <stdio.h>

char global[1000];

int main(void)
{
    printf("Please Enter Text: ");
    if (scanf("%s", global) == 1)
        printf("%s\n", global);
    return 0;
}

This is at least sound code, but it still has your original problem that it reads only one word, not a whole line.

Forget that gets() exists. It was one of the buggy functions used in the first Internet Worm of 1988 (Google for 'morris internet worm'). It is irredeemable; it cannot be used safely in a hostile environment, and all programming has to be done assuming a hostile environment.

To read a line, use fgets().

#include <stdio.h>
#include <string.h>

char global[1000];

int main(void)
{
    printf("Please Enter Text: ");
    if (fgets(global, sizeof(global), stdin) != NULL)
    {
        size_t len = strlen(global);
        if (len != 0 && global[len-1] == '\n')
            global[--len] = '\0';
        printf("%s\n", global);
    }
    return 0;
}

This gets a line of data into global.

You can legitimately ask how len could ever be zero (I asked it of myself, and I replaced assert(len != 0) because of the answer). One answer would be 'standard input was redirected from a binary file and the first byte was a null (zero) byte'. Then fgets() would read data including the null byte up to the first newline, but the strlen() would stop at the null byte, reporting 0 as the length.

The code removes the newline from the string, and determines its length at the same time — you normally need that length. It then prints it. Notice that the code checks that fgets() succeeded. I/O (especially input) has a habit of breaking when you aren't looking. A lot of the time, it will work fine, but to make your program robust, you have to be paranoid about input operations failing (and, later, memory allocations failing).

2 Comments

I note that the question asks about 'get a sentence' and not 'get a line'. Treating it as meaning 'get more than one word into a string' allows this answer. However, if you need a moderately strict definition of a sentence (a sequence of words ending with a full stop, exclamation mark or question mark, with complications like parentheses, quotes, and abbreviations to deal with), then this code is but a starting point, and not necessarily a good starting point. For reading a 'real sentence', you'd probably be better off using character by character input, pushing back unwanted spaces etc.
Oh, and the scanf() code should really use "%999s" as the format string to ensure that scanf() does not overflow the variable. Note the 'off-by-one' numbering; the length specified is the number of characters available excluding the null byte, hence the use of 999 when the buffer holds 1000 characters.
1

Are you looking for something like this:-

 scanf("%[^\t\n]",&global);

Also in your printf & is not required. It should be like:

printf("%s", global);

6 Comments

what does [^\t\n] mean?
@NewFile It is called scan set.
i got it working but i did &global instead of global, due to global gave me null as nothing is set by default in the global variable. Thanks
@NewFile:- Yes thats correct. I have updated my answer with that.! :)
This is because of the \n in your line!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.