Thread: Words with line numbers

  1. #1
    Registered User
    Join Date
    Oct 2020
    Posts
    69

    Words with line numbers

    Hello, I would like to know how can I print a line from a string, starting from a specific word. I have the following tasks:
    Write a program that prints all lines from input that contain a given word.
    Only the part of the line starting with the word must be printed.
    Prefix it with the line number.
    a) Consider only standalone words.
    b) Count also occurrences as substrings in other words.
    Handle arbitrarily long words.
    a) :
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #define MAX 100
    int main()
    {
        char s[MAX];
        char mask[MAX];
        char delim[] = "\n.!?, ";
        char wordString[] = "ana";
        unsigned lineCounter = 0;
        unsigned ok;
        while(fgets(s, sizeof s, stdin))
        {
            //printf("%s", s);
            lineCounter++;
            strcpy(mask, s);
            char* word = strtok(mask, delim);
            while(word != NULL)
            {
                if(strcmp(word, wordString) == 0)
                {
                    ok = 1; // if a word on the line coincides with the given word, stop comparing words => ok=1
                    break;
                }
                else
                {
                    ok = 0; // if ok=0 => there is no word coinciding with the given word on the line
                }
                word = strtok(NULL, delim);
            }
            //printf("%d", ok);
            if(ok == 1)
            {
    
    
                printf("%d  %s\n",lineCounter, s);
            }
            else
                printf("The line doesn't contain the given word.\n");
        }
        //printf("There are %d lines in the input.", lineCounter);
        return 0;
    }

    Input:
    andrew goes shopping.
    john saw ana in the park
    she goes shooping
    ana is singing
    Output :
    The line doesn't contain the given word.
    2 john saw ana in the park // this should be just "ana in the park"
    The line doesn't contain the given word.
    4 ana is singing

    I've solved b) in a similar fashion, only using strstr instead of strcmp, they're both working fine, I just want to know how can I print the line starting from the word I want.(I thought maybe I should use a for loop inside the second while and keep track of the position of the first letter of the word, but I think I'm missing an idea).

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    As soon as you've got some code working, refactor it to make functions out of it.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #define MAX 100
    
    int contains_word(const char *buff, const char *find)
    {
      char mask[MAX];
      char delim[] = "\n.!?, ";
      strcpy(mask, buff);
      char* word = strtok(mask, delim);
      int ok = 0;
      while(word != NULL)
      {
        if(strcmp(word, find) == 0)
        {
            ok = 1; // if a word on the line coincides with the given word, stop comparing words => ok=1
            break;
        }
        word = strtok(NULL, delim);
      }
      return ok;
    }
    
    int main()
    {
      char s[MAX];
      char wordString[] = "ana";
      unsigned lineCounter = 0;
      unsigned ok;
      while(fgets(s, sizeof s, stdin))
      {
        lineCounter++;
        if( contains_word(s, wordString) )
        {
          printf("%d  %s\n",lineCounter, s);
        }
        else
        {
          printf("The line doesn't contain the given word.\n");
        }
      }
    }
    Each function has a single well-defined purpose.

    > I just want to know how can I print the line starting from the word I want.
    > ... but I think I'm missing an idea).
    At the point where you do ok = 1, you can do this.
    Code:
    position = word - mask;
    Later on, you can do this.
    Code:
    printf("%d %s", lineCounter, &s[position] );
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Quote Originally Posted by Salem View Post
    As soon as you've got some code working, refactor it to make functions out of it.
    Code:
    #include <stdio.h>
    #include <ctype.h>
    #include <string.h>
    #define MAX 100
    
    int contains_word(const char *buff, const char *find)
    {
      char mask[MAX];
      char delim[] = "\n.!?, ";
      strcpy(mask, buff);
      char* word = strtok(mask, delim);
      int ok = 0;
      while(word != NULL)
      {
        if(strcmp(word, find) == 0)
        {
            ok = 1; // if a word on the line coincides with the given word, stop comparing words => ok=1
            break;
        }
        word = strtok(NULL, delim);
      }
      return ok;
    }
    
    int main()
    {
      char s[MAX];
      char wordString[] = "ana";
      unsigned lineCounter = 0;
      unsigned ok;
      while(fgets(s, sizeof s, stdin))
      {
        lineCounter++;
        if( contains_word(s, wordString) )
        {
          printf("%d  %s\n",lineCounter, s);
        }
        else
        {
          printf("The line doesn't contain the given word.\n");
        }
      }
    }
    Each function has a single well-defined purpose.

    > I just want to know how can I print the line starting from the word I want.
    > ... but I think I'm missing an idea).
    At the point where you do ok = 1, you can do this.
    Code:
    position = word - mask;
    Later on, you can do this.
    Code:
    printf("%d %s", lineCounter, &s[position] );
    Thanks a lot! It's working now but could you please explain something: if we subtract 2 strings, we basically get the difference in memory from the first string to the second, right? If so, why is position = word - mask and not mask - word, since mask is basically the "source"? I know it's fine like this because I tried the second one and it just printed garbage, but why?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Imagine that the address of mask was 1000. Then the address of word would start from 1000 onwards. So, if the address of word is 1004, word - mask = 4, whereas mask - word = -4, which wouldn't make sense as a position.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    Oct 2020
    Posts
    69
    Quote Originally Posted by laserlight View Post
    Imagine that the address of mask was 1000. Then the address of word would start from 1000 onwards. So, if the address of word is 1004, word - mask = 4, whereas mask - word = -4, which wouldn't make sense as a position.
    Oh okay, got it now. Thanks!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Numbers to words
    By Hool in forum C++ Programming
    Replies: 4
    Last Post: 12-20-2012, 04:07 AM
  2. Numbers to words
    By Dontgiveup in forum C++ Programming
    Replies: 28
    Last Post: 03-25-2011, 06:54 AM
  3. reading words line by line from a file
    By -EquinoX- in forum C Programming
    Replies: 3
    Last Post: 05-04-2008, 12:34 AM
  4. Replies: 5
    Last Post: 12-21-2007, 01:38 PM
  5. Numbers To words
    By Sesshokotsu in forum C Programming
    Replies: 3
    Last Post: 10-05-2006, 05:30 PM

Tags for this Thread