1
int count_words(string word)
{
    string spaces = "";
    int total_words = 1;
    int i, j = 0 ;
    for (i = 0;  i < strlen(word); i++)
    {
        strcpy(spaces, word[i]);
        if (strcmp(spaces, " ") == 0)
        {
            total_words = total_words + 1;
        }
    }
    return total_words;
}

I am trying to make a function in c that gets the total number of words, and my strategy is to find the number of spaces in the string input. However i get an error at strcpy about integer to ptrtype conversion,. I cant seem to compare the 2 strings without getting the error. Can someone explain to me whats how the error is happening and how I would go about fixing it. The IDE is also suggesting me to add an ampersand beside word[i] but it then makes a segmentation fault output

Steve Summit
  • 45,437
  • 7
  • 70
  • 103
SuperMage1
  • 131
  • 6
  • What is the `string` typedef? `strcpy` expects 2 char pointers but `word[i]` is a `char`. – 001 Jun 25 '21 at 14:35
  • Are you using C++? – Zois Tasoulas Jun 25 '21 at 14:36
  • 1
    Can you just check `if (word[i] == ' ') total_words += 1;`? – 001 Jun 25 '21 at 14:36
  • This is clearly c++ not c. You can't use strcpy with string type. It's only used with char array. For copying using strings just use a=b. – Nilanshu96 Jun 25 '21 at 14:38
  • Also, in `spaces` you are not storing a space character – Zois Tasoulas Jun 25 '21 at 14:38
  • 1
    `word[i]` is a char, and `spaces` is an immutable string (which contains a single byte `\0`). `strcpy(spaces, word[i])` is wrong for three reasons -- it copies a string, not a char, `spaces` is immutable and therefore an illegal target for `strcpy`, and it wouldn't have enough capacity to store a string containing a single character an its terminating \0. – Paul Hankin Jun 25 '21 at 14:39
  • As @JohnnyMopp mentioned, to check equality of characters you can use `==`. As long as you count the words by counting the number of spaces, you can try the code that @JohnnyMopp shared. Also `spaces` can be a `char` – Zois Tasoulas Jun 25 '21 at 14:40
  • You can't learn C effectively by guessing and then trying to debug, you need to have an understanding of what's going on. An introductory book on C would be a good start, and there's a good list here: https://stackoverflow.com/questions/562303/the-definitive-c-book-guide-and-list – Paul Hankin Jun 25 '21 at 14:41
  • I have done what @JohnnyMopp previously, but an error occurs "comparision between pointer and integer. This was my first solution . – SuperMage1 Jun 25 '21 at 14:48
  • sorry I didnt put enough context, this is the one with the online course of harvard where they have numerous add ons to c if im not mistaken, – SuperMage1 Jun 25 '21 at 14:49
  • 2
    @SuperMage1 You didn't read JohnnyMopp's suggestion carefully enough. `" "` is not the same as `' '`. – Steve Summit Jun 25 '21 at 14:52
  • Once you get this working, you can try to improve it so that it does the right thing if there are multiple spaces between words. – Steve Summit Jun 25 '21 at 15:03
  • 3
    @Nilanshu96 No, it's clearly C. SuperMage1 has confirmed that he's taking CS50, where they try to help the beginners by giving them a standard header file containing, among other things, `typedef char *string;`, to make it *look* like C has a string type. Needless to say this confuses things even worse. – Steve Summit Jun 25 '21 at 15:06
  • @steve-summit There wasn't a mention of it when I had commented. It definitely is confusing to use string without mentioning that it's a typedef on char*. – Nilanshu96 Jun 25 '21 at 16:16

1 Answers1

3

You need to learn a little more about the distinction between characters and strings in C.

When you say

strcpy(spaces, word[i]);

it looks like you're trying to copy one character to a string, so that in the next line you can do

if (strcmp(spaces, " ") == 0)

to compare the string against a string consisting of one space character.

Now, it's true, if you're trying to compare two strings, you do have to call strcmp. Something like

if (spaces == " ")        /* WRONG */

definitely won't cut it.

In this case, though, you don't need to compare strings. You're inspecting your input a character at a time, so you can get away with a simple character comparison instead. Get rid of the spaces string and the call to strcpy, and just do

if (word[i] == ' ')

Notice that I'm comparing against the character ' ', not the string " ". Using == to compare single characters like this is perfectly fine.

Sometimes, you do have to construct a string out of individual characters, "by hand", but when you do, it's a little more elaborate. It would look like this:

char spaces[2];
spaces[0] = word[i];
spaces[1] = '\0';
if (strcmp(spaces, " ") == 0)
    ...

This would work, and you might want to try it to be sure, but it's overkill, and there's no reason to write it that way, except perhaps as a learning exercise.

Why didn't your code

strcpy(spaces, word[i]);

work? What did the error about "integer to pointer conversion" mean? Actually there are several things wrong here.

  1. It's not clear what the actual type of the string spaces is (more on this later), but it has space for at most 0 characters, so you're not going to be able to copy a 1-character string into it.
  2. It's also not clear that spaces is even writable. It might be a constant, meaning that you can't legally copy any characters into it.
  3. Finally, strcpy copies one string to another. In C, although strings are arrays, they're usually referred to as pointers. So strcpy accepts two pointers, one to the source and one to the destination string. But you passed it word[i], which is a single character, not a string. Let's say the character was A. If you hadn't gotten the error, and if strcpy had tried to do its job, it would have treated A as a pointer, and it would have tried to copy a string from address 65 in memory (because the ASCII value of the character A is 65).

This example shows that working with strings is a little bit tricky in C. Strings are represented as arrays, but arrays are second-class citizens in C. You can't pass arrays around, but arrays are usually referred to by simple pointers to their first element, which you can pass around. This turns out to be very convenient and efficient once you understand it, but it's confusing at first, and takes some getting used to.

It might be nice if C did have a built-in, first-class string type, but it does not. Since it does not, C programmers myst always keep in mind the distinction between arrays and characters when working with strings. That "convenient" string typedef they give you in CS50 turns out to be a bad idea, because it's not actually convenient at all -- it merely hides an important distinction, and ends up making things even more confusing.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103