-2

I am trying to split strings into words. Can anyone help me on how to implement it without using strtok and another function other than main?

void main()
{
    int i;
    int myargc = 1;
    char *myargv[256];
    char buff[100];
    int len = 0;
    char string[256];
    int j = 0;

    printf("Enter text: ");
    gets(buff);

    for(i = 0; buff[i] != '\0'; i++){
        len++;
    }

    for(i = 0; i < len; i++)
    {
        if(buff[i]!=' ' && buff[i+1]==' ')
        {
            myargc++;
        }
    }
    printf("myargc %d\n",myargc);

    **for(i = 0; i < len; i++){
        if(buff[i] != ' '){
            string[j++] = buff[i];
        }
        if(buff[i] != ' ' && buff[i] == ' '){
            string[j++] = '\0';
            j = 0;
        }
        if(buff[i] == '\0'){
            break;
        }
    }**
    for(i = 0; i < myargc - 1; i++){
        myargv[i] = string;
        printf("argv[%d]\t%s\n", i, myargv[i]);
    }
}

When I entered "a b c" for example, my output looked like this:

myargc 3
argv[0] abc
argv[1] abc
argv[2] abc
anatolyg
  • 26,506
  • 9
  • 60
  • 134
jsrookie
  • 15
  • 1
  • 4
  • You are not allocating any memory for the pointers in `myargv[]` or copying any strings - you're just assigning pointers. – Paul R Aug 08 '18 at 14:41
  • 1
    Each element of `myargv[]` points to `string[]` whose content keeps changing. So they all point to the same thing, the last string processed. – Weather Vane Aug 08 '18 at 14:44
  • @PaulR is it correct that I assign the buff[i] == ' ' into buff[i] = '\0' and then I perform the string copy after? – jsrookie Aug 08 '18 at 14:55
  • It sounds like you may need to learn how to use a [debugger](https://en.wikipedia.org/wiki/Debugger) to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Paul R Aug 08 '18 at 15:40

1 Answers1

0

So here is my solution, not sure if it is optimal, but works also with more spaces between words.

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

void main()
{
    int i;
    int myargc = 1;
    char **myargv;
    char buff[100];
    int len = 0;
    char string[256];
    int j = 0, k =0;

    printf("Enter text: ");
    gets(buff);

    for(i = 0; buff[i] != '\0'; i++){
        len++;
    }

    for(i = 0; i < len; i++)
    {
        if(buff[i]!=' ' && buff[i+1]==' ')
        {
            myargc++;
        }
    }
    printf("myargc %d\n",myargc);

    //allocating 256 bytes * number of words    
    myargv = (char**)malloc(myargc*sizeof(char*));
    for(i = 0; i < myargc; i++){
        myargv[i] = (char*)malloc(256*sizeof(char));
    }

    //iterating until the ending character
    for(i = 0; i <= len; i++){
        //building word
        if(buff[i] != ' ' && buff[i] != 0)
        {   
            string[j++] = buff[i];
        }

        //copying word to corresponding array
        else if((buff[i] == ' ' && buff[i+1] != ' ') || (buff[i] == 0))
        {
            for(int z = 0; z < j; z++){
                myargv[k][z] = string[z];
            }

            myargv[k++][j] = '\0';
            j = 0;
        }

        //skipping more spaces in a row
        else continue;
    }


    for(i = 0; i < myargc; i++){
        printf("argv[%d]\t%s\n", i, myargv[i]);
    }

    }
Marlon23
  • 28
  • 4
  • Thanks for the help. I wanted to ask what's the difference between char **myargv and char *myargv[256]. I tried to search on it but I can't find a more detailed explanation about their difference. – jsrookie Aug 09 '18 at 13:31
  • Check this website: https://cdecl.org. So according to your declaration, you declared myargv as an array of 256 pointers to char. In your situation when you don't know how many words you'll get, I think dynamic allocation is good solution for saving memory. At first, you allocate as many pointers to char as you have words. The second step is forloop and for every pointer to char you need to allocate some memory to store the strings. That's why there are two stars in declaration. – Marlon23 Aug 09 '18 at 20:03
  • I think that the problem wasn't in your declaration of myargv, but in splitting the original string. In your highlighted forloop, you just erased spaces, second condition had never executed, because if the first part of condition is true, the second part can't be true. And in the last forloop, your joined string was assigned to each pointer from array, so the output was still the same. – Marlon23 Aug 09 '18 at 20:15