2

I have recently started learning C, and I made this small piece of code, but it's not really working the way I wanted:

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

int main()
{
    int i;
    char a[] = "Bill Sarah Alice";
    for (i = 0; a[i] != '\0'; i++)
    {
        if (a[i] != '\t' || a[i] != ' ')
        {
            printf("%c", a[i]);
        }
        putchar('\n');
    }
    return 0;
}

I wanted to print one name per line, but instead its printing one character per line. Can someone tell how should I fix it so it will work?

anastaciu
  • 23,467
  • 7
  • 28
  • 53
Meg
  • 29
  • 2

5 Answers5

1
     if(a[i] != '\t' || a[i] != ' '){

Every character is not tab or not space. So this if will be passed by every single character. You then output a newline after every single character. So this code is equivalent to this:

  for(i=0; a[i] != '\0'; i++){
     printf("%c", a[i]);
     putchar('\n');
  }

If you want to print each name on a line, you need to do something more like this:

  for(i=0; a[i] != '\0'; i++){
     if(a[i] == '\t' || a[i] == ' ')
        putchar('\n');
     else
        printf("%c", a[i]);
  }
  putchar('\n');
David Schwartz
  • 179,497
  • 17
  • 214
  • 278
1

Alternatively to other answers you can use isspace to detect spaces or tabs:

#include <ctype.h> // for isspace()
#include <stdio.h> 


int main()
{
    int i;
    char a[] = "Bill Sarah Alice";
    for (i = 0; a[i] != '\0'; i++)
    {
        if (!isspace(a[i])) // if it's not a space
        {
            printf("%c", a[i]); // print character
        }
        else
            putchar('\n'); // if it is print a newline
    }
}

Output:

Bill
Sarah
Alice
anastaciu
  • 23,467
  • 7
  • 28
  • 53
  • 1
    I would probably recommend `isspace` instead, since that one also looks for new line. Not applicable in this specific case, but whenever you take input from stdin etc. – Lundin Mar 31 '21 at 09:36
  • @Lundin, yes, it's more appropriate. – anastaciu Mar 31 '21 at 09:38
0

There are two issues in your code. First, the newline character will be printed on every run through the for loop; to fix this, put the putchar('\n'); line into an else block.

Second, your test condition is wrong and can never be false: the character cannot be both a tab and a space, so one of the != tests will always be true; to fix this, change the || to a &&.

int main()
{
    int i;
    char a[] = "Bill Sarah Alice";
    for (i = 0; a[i] != '\0'; i++) {
        if (a[i] != '\t' && a[i] != ' ') {
            printf("%c", a[i]);
        }
        else {
            putchar('\n');
        }
    }
    return 0;
}
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
0

Within the for loop an output of the new line character '\n' is executed after printing each character in the string that is not equal to '\t' or to ' '.

     if(a[i] != '\t' || a[i] != ' '){
        printf("%c", a[i]);
     }
     putchar('\n');

Moreover the condition in the if statement shall be written at least like

     if(a[i] != '\t' && a[i] != ' '){
                    ^^^^

You need to output the new line character after a whole name is outputted. So if you are outputting a name character by character then you need one more inner loop.

Also the header <string.h> is redundant because neither declaration from the header is used in your program. So you may remove the directive

#include <string.h>

The algorithm can look the following way as it is shown in the demonstrative program below. It is implemented as a separate function.

#include <stdio.h>

void print_names( const char *s )
{
    while ( *s != '\0' )
    {
        while ( *s == ' ' || *s == '\t' ) ++s;
        while ( *s && *s != ' ' && *s != '\t' ) putchar( *s++ );
        putchar( '\n' );
    }
}

int main(void) 
{
    char a[] = "Bill Sarah Alice";

    print_names( a );
    
    return 0;
}

The program output is

Bill
Sarah
Alice

If to include the header <ctype.h>

#include <ctype.h>

then the function can be rewritten using the standard C function isblank that itself does the check whether a character is equal to the space character or to the tab character.

#include <stdio.h>
#include <ctype.h>

void print_names( const char *s )
{
    while ( *s != '\0' )
    {
        while ( isblank( ( unsigned char )*s ) ) ++s;
        while ( *s && !isblank( ( unsigned char )*s ) ) putchar( *s++ );
        putchar( '\n' );
    }
}
//...
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
-1

What you want, is the function strtok(3).

strtok uses a delimiter string to return parts of the string. By using " " as a delimiter, you can easily extract the names. For how to use the function read the man page I linked above. Or read this article.

You can print the names one at a time using the following code

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

int main
(int argc, char *argv[], char *envp[])
{
        char a[] = "Bill Sarah Alice";
        char *tok = strtok (a, " ");
        while (tok) {
                puts (tok);
                tok = strtok (NULL, " ");
        }
        return 0;
}
debdutdeb
  • 133
  • 7
  • 1
    The problem with `strtok` is that it destroys the original string though. So if the code is changed to `char* a` you suddenly get a crash. It's one of those functions that tends to create more problems than it solves. – Lundin Mar 31 '21 at 09:38