SoSueat
SoSueat

Reputation: 63

C, counting the number of blankspaces

I'm writing a function that replaces blank spaces into '-' (<- this character). I ultimately want to return how many changes I made.

#include <stdio.h>
int replace(char c[])
{
    int i, cnt;
    cnt = 0;
    for (i = 0; c[i] != EOF; i++)
        if (c[i]==' ' || c[i] == '\t' || c[i] == '\n')
        {
            c[i] = '-';
            ++cnt;
        }
    return cnt;
}

main()
{
    char cat[] = "The cat sat";
    int n = replace(cat);
    printf("%d\n", n);
}

The problem is, it correctly changes the string into "The-cat-sat" but for n, it returns the value 3, when it's supposed to return 2. What have I done wrong?

Upvotes: 6

Views: 135

Answers (4)

Nik
Nik

Reputation: 1870

@4386427 suggested this should be another answer. @wildplasser already provided the solution, this answer explains EOF and '\0'.

You would use EOF only when reading from a file (EOF -> End Of File). See this discussion. EOF is used to denote the end of file, and its value is system dependent. In fact, EOF is rather a condition than a value. You can find great explainations in this thread. When working with char array or a char pointer, it will always be terminated by a '\0' character, and there is always exactly one of those, thus, you would use it to break out of the loop when iterating through an array/pointer. This is a sure way to ensure that you don't access memory that is not allocated.

Upvotes: 1

Chakra Jamdagneya
Chakra Jamdagneya

Reputation: 24

EOF used in the for loop end condition is the problem as you are not using is to check end of file/stream.

for (i = 0; c[i] != EOF; i++)

EOF itself is not a character, but a signal that there are no more characters available in the stream.

If you are trying to check end of line please use

for (i = 0; c[i] != "\0"; i++)

Upvotes: 0

wildplasser
wildplasser

Reputation: 44250

  • A string ends with a 0 (zero) value, not an EOF (so: the program in the question will scan the string beyond the terminal\0 until it happens to find a -1 somewhere beyond; but you are already in UB land, here)
  • [sylistic] the function argument could be a character pointer (an array argument cannot exist in C)
  • [stylistic] a pointer version wont need the 'i' variable.
  • [stylistic] The count can never be negative: intuitively an unsigned counter is preferred. (it could even be a size_t, just like the other string functions)
  • [stylistic] a switch(){} can avoid the (IMO) ugly || list, it is also easier to add cases.

unsigned replace(char *cp){
    unsigned cnt;
    for(cnt = 0; *cp ; cp++) {
        switch (*cp){
        case ' ' : case '\t': case '\n':
                *cp = '-';
                cnt++; 
        default:
                break;
                }
        }
return cnt;
}

Upvotes: 0

Sergei Nazarenko
Sergei Nazarenko

Reputation: 39

#include <stdio.h>

int repl(int c);

int main(void){
    int c, nc;
    nc =0;

    while ((c=getchar())!=EOF)
        nc = replc(c);

    printf("replaced: %d times\n", nc);

    return 0;
}

int replc(int c){
    int nc = 0;
    for(; (c = getchar())!=EOF; ++c)
       if (c == ' '){
          putchar('-');
          ++nc;
       } else putchar(c);
    return nc;
}

Upvotes: 0

Related Questions