0

I'm trying to split a sentence the user inputs to an array of words so I can later manipulate the words separately as strings. The code is compiling but prints only garbage after the user input. I tried debugging but don't see the problem. Can someone help me fix it?

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

int main() {
    char str[1000];
    int i = 0;
    char rev[1000][1000];
    int r = 0;

    puts("Enter text:");

    gets(str);

    int k, length = 0;
    printf_s("So the words are:\n");
    while (str[i] != '\0') {
        if (str[i] == ' ') {
            k = i - length;

            do {
                rev[r][k] = (str[k]);
                k++;
            } while (str[k] != ' ');
            printf(" ");
            length = (-1);
            r++;
        } else
        if (str[i + 1] == '\0') {
            k = i - length;

            do {
                rev[r][k] = (str[k]);
                k++;
            } while (str[k] != '\0');
            length = 0;
            r++;
        }

        length++;
        i++;
    }
    for (int r = 0; r < 1000; r++) 
        printf("%s ", rev[r]);

    return 0;
}
chqrlie
  • 131,814
  • 10
  • 121
  • 189
raf_OH
  • 11
  • 3

4 Answers4

0

If you wish to split a string into an array of strings, you should consider the strtok function from #include <string.h>. The strtok function will the split the string on the given delimiter(s). For your case, it would the " ".

Using the strtok example from Tutorials Point:

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

int main(){
   char str[80] = "This is - www.tutorialspoint.com - website";//The string you wish to split
   const char s[] = "-";//The thing you want it to split from. But there is no need to this.
   char *token;//Storing the string
   
   /* get the first token */
   token = strtok(str, s);//Split str one time using the delimiter s
   
   /* walk through other tokens */
   while( token != NULL ) 
   {
      printf( " %s\n", token );//Print the string
    
      token = strtok(NULL, s);//Split the string again using the delimiter
   }
   
   return(0);
}
Manav Dubey
  • 780
  • 11
  • 26
  • Judging from the code, the site is Tutorials Point rather than Tutorial Points. It would be a good idea to include a link to the site and where you found the code. Do their terms of use permit you to copy the code here? – Jonathan Leffler May 19 '17 at 17:19
0

Replace you declaration

char rev[1000][1000];

with

char * rev[1000];                  // We will need pointers only
int    i = 0;                      // Index to previous array

and all your code after

    puts( "Enter text:" );

with this:

    fgets( str, 998, stdin );      // Safe way; don't use gets(str)

    const char delim[] = ",; ";    // Possible delimiters - comma, semicolon, space
    char *word;

    /* Get the first word */
    word     = strtok( str, delim );
    rev[i++] = word; 

    /* Get the next words */
    while( word != NULL ) 
    {
       word     = strtok( NULL, delim );
       rev[i++] = word;
    }

    /* Testing */
    for (int r = 0; r < i - 1; r++) 
        printf( "%s\n", rev[r] );

    return 0
}

As you can see, all dirty work is done with the strtok() function ("string to tokens") which walks through other and other words ("tokens"), recognizing them as delimited by one or more characters from the string delim.


MarianD
  • 13,096
  • 12
  • 42
  • 54
  • 1
    Why `998` for size in `fgets()` when str is a buffer with size 1000 *and* `fgets()` reads in "... at most **one less** than size ..." (at least according to `man fgets`)? – SiggiSv May 19 '17 at 14:06
  • @SiggiSv - You are probably right, I'm too lazy to read the documentation so I used some smaller value for the safety :-) – MarianD May 19 '17 at 14:29
0

fix like this

#include <stdio.h> 

int main(void) {
    char str[1000];
    char rev[1000][1000];

    puts("Enter text:");
    fgets(str, sizeof str, stdin);//Use fgets instead of gets. It has already been abolished.

    int r = 0;
    int k = 0;

    for(int i = 0; str[i] != '\0'; ++i){
        if (str[i] == ' ' || str[i] == '\n'){//is delimiter
            if(k != 0){
                rev[r++][k] = '\0';//add null-terminator and increment rows
                k = 0;//reset store position
            }
        } else {
            rev[r][k++] = str[i];
        }
    }
    if(k != 0)//Lastly there was no delimiter
        rev[r++][k] = '\0';

    puts("So the words are:");
    for (int i = 0; i < r; i++){
        printf("%s", rev[i]);
        if(i < r - 2)
            printf(", ");
        else if(i == r - 2)
            printf(" and ");
    }

    return 0;
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int count_spaces(char *str)
{
  if (str == NULL || strlen(str) <= 0)
    return (0);

  int i = 0, count = 0;
  while (str[i])
    {
      if (str[i] == ' ')
    count++;
      i++;
    }

  return (count);
}

int count_char_from_pos(char *str, int pos)
{
  if (str == NULL || strlen(str) <= 0)
    return 0;

  int i = pos, count = 0;
  while (str[i] && str[i] != ' ')
    {
      count++;
      i++;
    }

  return count;
}

char **get_words(char *str)
{
  if (str == NULL || strlen(str) <= 0)
    {
      printf("Bad string inputed");
      return NULL;
    }

  int i = 0, j = 0, k = 0;
  char **dest;

    if ((dest = malloc(sizeof(char*) * (count_spaces(str) + 1))) == NULL
    || (dest[0] = malloc(sizeof(char) * (count_char_from_pos(str, 0) + 1))) == NULL)
      {
    printf("Malloc failed\n");
    return NULL;
      }

  while (str[i])
    {
      if (str[i] == ' ') {
    dest[j++][k] = '\0';
      if ((dest[j] = malloc(sizeof(char) * (count_char_from_pos(str, i) + 1))) == NULL)
        {
          printf("Malloc failed\n");
          return NULL;
        }
      k = 0;
    }
      else { 
      dest[j][k++] = str[i];
    }

      i++;
    }

  dest[j][k] = 0;
  dest[j + 1] = NULL;
  return dest;
}

int main(void) {
    char *line = NULL;
    size_t n = 0;
    getline(&line, &n, stdin);
    printf("%s\n", line);
    line[strlen(line) - 1] = 0;
    printf("%s\n", line);

    char **tab = get_words(line);

    int i = 0;
    while (tab[i])
      {
    printf("%s\n", tab[i++]);
      }
}

here is a long but fully working example get the user input then send it to get_words function. It will get the number of words, the number of characters for each words, allocate everything in memory and writes chars then return it. You get a char ** and prints it just tested it it works

RomMer
  • 909
  • 1
  • 8
  • 19