0

I am writing a code that takes a string as input and prints every word in the string in a newline.

I am using pointer arithmetic for this purpose

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

int main() {
  char *s;
  s = malloc(1024 * sizeof(char));
  scanf("%[^\n]", s);
  s = realloc(s, strlen(s) + 1);
  while (*s != '\0') {
    if (*s == ' ') {
      printf("\n");
    } else {
      printf("%s", s);
    }
    s++;
  }
  return 0;
}

Input:

i am a beginner. \n  

Output:

i am a beginner \n   
am a beginnerm a beginner \n   
a beginner \n
beginnereginnerginnerinnernnernererr
Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • 1
    You’re printing the whole string from the current position to the end each time, not just one character. – mkrieger1 Aug 11 '19 at 08:57
  • Change this `printf("%s", s);` to `printf("%c", *s);` – Alex Lop. Aug 11 '19 at 08:58
  • Why not use `free()` (after all the trouble to `realloc()`)? It's only a little bit more trouble and it pays to be thorough :) – pmg Aug 11 '19 at 08:58
  • Possible duplicate of [Output single character in C](https://stackoverflow.com/questions/310032/output-single-character-in-c) – mkrieger1 Aug 11 '19 at 09:00

3 Answers3

1

Instead of %s you need %c to print a single character. Besides that, you don't need to free the memory you get from malloc since realloc takes care of that, but you have to free the memory you got from realloc. Yes, the OS will clean up after you, but it is best to release the resources you acquired. In order to do the free we are going to not change the value of s, instead we are going to copy it. Here is the fixed version:

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

int main() {
  char* s;
  s = malloc(1024 * sizeof(char));
  scanf("%[^\n]", s);
  char* p = s = realloc(s, strlen(s) + 1);
  while (*p != '\0') {
    if (*p == ' ') {
      printf("\n");
    } else {
      printf("%c", *p);
    }
    ++p;
  }
  free(s);
  return 0;
}

Input:

My awesome input

Output:

My
awesome
input

A few points for you to consider. If the user adds multiple space characters in between words or adds something like '\t', your program doesn't handle the case correctly.

Aykhan Hagverdili
  • 28,141
  • 6
  • 41
  • 93
  • Do suggest OP to `free()` dynamic memory to avoid memory leakage. Also due to `s++` `s` no longer points initial dynamic memory address, to free it, need to keep track of initial `s`. – Achal Aug 11 '19 at 09:06
1

I would say its not very logical to reinvent the wheel unless you need some extra functionality or portability. Same can be done more reliably like:

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

int main()
{
    char *s;
    s = malloc(1024 * sizeof(char));
    scanf("%[^\n]", s);

    char *to_free = s = realloc(s, strlen(s) + 1);
    char *word;

    while ((word = strsep(&s, " \t")) != NULL)
        printf("%s\n", word);

    free(to_free);

    return 0;
}

This also allows you to keep track of tabs as well as spaces(as you are considering words). Notice the argument passed to strsep, its a space and a tab. You could easily separate words using ,, . etc as well by just adding these delimeters to the strsep argument.

Also it is a good practice to free the memory you allocated.

Mihir Luthra
  • 6,059
  • 3
  • 14
  • 39
0

if you use printf with "%s" it prints out the entire string all the way to \0.

that's why you see the entire sentence in every line (minus a few characters from the start).

the way you used pointers in this code, I'm guessing you're trying print out individual characters, so just switch "%s" with "%c"

BarSahar
  • 69
  • 1
  • 4