6

I have a void function which take the string from a global variable and prints them.

The problem is that the void function prints a message/does stuff even if the string is empy. so if the global variable is empt it just prints "message is:" i only want to do something if the string has characters.

what i want to do is to check if the string is not empty, then print a message.

// global variable

char msg[30];
scanf("%s", &msg);

void timer(void) {
    //i want to only print if there is a message
    printf("message: %s", msg);
}

thanks for any help

MD XF
  • 7,860
  • 7
  • 40
  • 71

7 Answers7

16

The easy way to do it would be like this:

if (msg[0])
    printf("message: %s", msg);

If, at some later date, msg is a pointer, you would first want to assure it's not a NULL pointer.

if (msg && msg[0])
    printf("message: %s", msg);

A test program to demonstrate:

#include <stdio.h>
#include <stdlib.h>

char *msg;

void test() {
    if (msg && msg[0])
        printf("string is %s\n", msg);
}

int main()
{
    msg = NULL;
    test();
    msg = calloc(10, 1);
    test();
    msg[0] = 'm';
    msg[1] = 'e';
    test();
    free(msg);
}

On my machine the output is:

string is me

Edward
  • 6,964
  • 2
  • 29
  • 55
  • 1
    I think there is no difference between `msg && msg[0]` and `msg[0]` ?? – Amit Sharma Oct 28 '14 at 13:28
  • 2
    If it's defined as `char *msg` the difference is that `msg[0]` refers to the first character and `msg` refers to the pointer itself. – Edward Oct 28 '14 at 13:30
  • You can always write `msg` as `msg[0]` because it will treated as `*(msg+0)` which is exactly the same as `msg`. Array name is just a constant pointer .So how it make difference, here – Amit Sharma Oct 28 '14 at 13:39
  • @AmitSharma no. `msg` evaluates to the address of the first `char`. `msg[0]` is the same as `*(msg+0)` but **not** `msg`. `msg && msg[0]` is true when the pointer is: not null. references a `char` with a non-zero value. It also short-circits, so it won't try to dereference a null pointer. – Baldrickk Oct 28 '14 at 13:42
  • @AmitSharma: I've added a silly little test program to the answer. Try it. – Edward Oct 28 '14 at 13:44
11

Strings in C are represented as character arrays, terminated by a character whose value is zero (often written as '\0'). The length of a string is the number of characters that come before the zero.

So, a string is empty if the first character in the array is zero, since then by definition no characters came before the zero.

This can be checked like so:

if(msg[0] != '\0')
{
  /* string isn't empty! */
}

This is very explicit code, the shorter if(msg[0]) or if(*msg) has the exact same semantics but can be slightly harder to read. It's mostly a matter of personal style.

Note though that in your case, when you use scanf() to read into msg, you should check the return value from scanf() before checking the contents of msg. It's perfectly possible for scanf() to fail, and then you can't rely on msg being set to an empty string.

unwind
  • 391,730
  • 64
  • 469
  • 606
  • +1 for mentioning return of scanf(). (nobody else saw that as an issue.) – ryyker Oct 28 '14 at 14:51
  • @ryyker Nobody *ever* does, around here. – unwind Oct 28 '14 at 14:52
  • One could also note that the use of a global variable is probably not a good idea either. Seemed orthogonal to the question asked, though, so I didn't include it in my answer. – Edward Oct 28 '14 at 14:58
  • @Edward - true especially for embedded, but outside of embedded, there are places where globals are useful. eg. `extern` scoped struct arrays provide simplicity, and the cost is very affordable when memory is so cheap. (for applications running on a desktop, for example) – ryyker Oct 28 '14 at 15:52
  • @ryyker: While there may well be instances where a global variable is needed, this is certainly not one of them. – Edward Oct 28 '14 at 21:08
  • @Edward - In my previous comment, I was careful to use the phrase _are useful_. In my experience, globals are rarely _needed_, just expedient. And again, Absent of a specification, it would be hard to ague against using one here. Saying _don't ever use globals_ is similar to saying _don't ever cast the output of malloc or calloc._ Most of the time the advice is right on, but other time, its just fine to cast, or use a global. (in the case of casting malloc/calloc, some C implementations require the cast.) – ryyker Oct 28 '14 at 21:42
  • @ryyker What C implementations would that be? Very old ones? – unwind Oct 29 '14 at 07:58
  • @unwind - Some old ones, yes. And for people using a C++ compiler wanting to write code portable to C. But you know all that better than most. (And yeah, I know, I was not specific in that example, and I said C..., give me a break :) The main point was that asserting dogmas where the standard doesn't is short sighted, and at best conveys an idea that is not often generally applicable. Blanket statements should be rarely be made _about when and when not to use globals_. Very small embedded projects, okay, don't use globals. In a Windows, desktop application, use all you want. – ryyker Oct 29 '14 at 13:57
3

This should work for you:

The Message will only be printed if it's longer then 0.

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

void timer() {

    char msg[30];
    scanf(" %s", msg);

    if(strlen(msg) != 0)
        printf("message: %s", msg);
}

int main() {

    timer();

    return 0; 
}
Rizier123
  • 58,877
  • 16
  • 101
  • 156
1

Here are all the ways I found (and can think of) to check if a string is empty. Sorted by efficiency.

  • msg[0] == '\0'
  • strlen(msg) == 0
  • !strcmp(msg, "")

And this, which should only happen if the user somehow avoided input (e.g. with Ctrl+Z) or there was an error

  • scanf("%s", &msg) <= 0
MD XF
  • 7,860
  • 7
  • 40
  • 71
0

I think a quick and easy solution is to use strlen() in string.h to check the length of the string. if 0 then it is empty.

For example

// Check string is NOT empty.
if (strlen(current_word) > 0)
            {
                printf("%s %lu", current_word, strlen(current_word));
                strcpy(current_word, "");
                print_line();
            }
Gerald H
  • 454
  • 4
  • 13
0
  1. Using Strlen() function.
  2. Comparing with NULL string using strcmp();
  3. Checking first character is equal to '\0'.
  4. If string is inputted using scanf then check for return value of scanf() function

1st method:

char msg[30];

scanf("%s", &msg);

void timer(void) {

if(strlen(msg)>0)

printf("message: %s", msg);

}

2nd method:

char msg[30];

scanf("%s", &msg);

void timer(void) {

if(strcmp(msg,"")!=0)

printf("message: %s", msg);

}

3rd method:

char msg[30];

scanf("%s", &msg);

void timer(void) {

if(msg[0]!='\0')

printf("message: %s", msg);

}

4th method:

char msg[30];

int rv=scanf("%s", &msg);

void timer(void) {

if(rv>0)

printf("message: %s", msg);

}

For your reference about c string

https://www.programiz.com/c-programming/c-strings

https://www.geeksforgeeks.org/strings-in-c-2/

https://scholarsoul.com/string-in-c/

https://www.guru99.com/c-strings.html

Pranu Pranav
  • 353
  • 3
  • 8
-1

Ok,you can try this:

char msg[30];
scanf("%s",&msg);

void timer(void)
{
    //i want to only print if there is a message
    if(!msg.length == 0 )
        printf("message: %s", msg);
}

`