Link to home
Start Free TrialLog in
Avatar of yllee
yllee

asked on

Beginner in C programming

I just pick up C programming recently.  I come across following problem in my reference book which I failed to code them.

Could anyone please help me solve it? 

 
<<=============================================================================>>
 
Write a program that reads up to a maximum of 50 lines of text, each line containing up to a maximum of 80 characters, and then prints (on screen) all the words on each line in alphabetical order.  For example, the input
 
All in the golden afternoon
Full leisurely we glide; 
For both our oars, with little skill, 
By little arms are plied. 
 
would produce
 
afternoon All golden in the
Full glide; leisurely we 
Both for little oars, our skill, with 
are arms By little plied. 
 
<<=================================================================================>>
 
Write a program that reads up to a maximum of 50 lines of text, each line containing up to a maximum of 80 characters, and then prints (on screen) all the words on each line in reverse order.  For example, the input
 
All in the golden afternoon
Full leisurely we glide; 
For both our oars, with little skill, 
By little arms are plied. 
 
would produce
 
By little arms are plied. 
For both our oars, with little skill, 
Full leisurely we glide; 
All in the golden afternoon
 
<<===============================================================================>>
 
Write a program that reads up to a maximum of 50 lines of text, each line containing up to a maximum of 80 characters, and then prints (on screen) all the words on each line in reverse order.  For example, the input
 
All in the golden afternoon
Full leisurely we glide; 
For both our oars, with little skill, 
By little arms are plied. 
 
would produce
 
afternoon golden the in All
skill, little with oars, our both For
glide; we leisurely Full 
plied. are arms little By 

--------------------------------------------------------------------------------------------------------------------------------------------------------

Thank you very much in advance.
 
 
ASKER CERTIFIED SOLUTION
Avatar of kinkajou
kinkajou

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Is it a homework you have to do for school?
If so I will give you some advice how to begin
but to learn C you should code the program yourself.
it is not a big deal:
First because you have the restriction 50/80
create a array char Strings[50][80]
there you can strore the lines from the file
for each line you read from file increment a counter so you know how many lines you have
the second job then is nearly done:
int i;
for (i=NumberOfLines-1;i>=0;i--)
{
    printf("%s",Strings[i]);
}
for the other 2 jobs you have to split the lines
strtok will do that
I think that will be enough to begin
}

Avatar of kinkajou
kinkajou

yllee,  this is taking a bit of time but I think you'll be please with the results. Answer coming...
yllee, done with opposite and reverse and finishing alpha order, answer coming...
yllee,

There is error in the requirements you wrote above. In the alphabetical ouput you specified, "Both" should not be capitolized but "For" should be. Also, The reverse order output you specified had two lines "skill, little with oars, our both For" and "glide; we leisurely Full" switched, at least I am assuming. And I only know from finishing the program. I will post it below. I have an executable for your demonstration. If you want to give you email address, I will send it to you. I can also send you the program files in zip form if you want. Sorry it took so long, it's been a while since I coded this sort of program.

Good Luck!
Kinkajou



/* Write a program that reads up to a maximum of 50 lines of text,
   each line containing up to a maximum of 80 characters, and then
   prints (on screen) all the words on each line in alphabetical order.  

Additional assumptions: you are on a MSDOS machine.
*/

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

#define MAX_LINES 50
#define MAX_CHAR 80
#define TRUE 1
#define FALSE 0
#define DEBUG 1

/* function prototypes */
void getInput (char buffer[MAX_LINES][MAX_CHAR+1]);
void printOutput (char buffer[MAX_LINES][MAX_CHAR+1]);
void arrangeAlpha (char destination[MAX_LINES][MAX_CHAR+1], char source[MAX_LINES][MAX_CHAR+1]);
void arrangeReverse (char destination[MAX_LINES][MAX_CHAR+1], char source[MAX_LINES][MAX_CHAR+1]);
void arrangeOpposite (char destination[MAX_LINES][MAX_CHAR+1], char source[MAX_LINES][MAX_CHAR+1]);
int getWordCount (char string[MAX_CHAR+1]);
void removeWord (char line[MAX_CHAR+1], int pos);

/* global definitins */
int total_lines_of_input = 0;

void main (void)
{
  char input[MAX_LINES][MAX_CHAR+1]; /* array to hold user input from keyboard */
  char output[MAX_LINES][MAX_CHAR+1]; /* array for arranged output */

  getInput (input);
  printf ("Displaying the Original\n\n");
  printOutput (input);
  printf ("Hit any key to contine...");
  getchar ();

  printf ("Displaying Alphabetical ordered lines\n\n");
  arrangeAlpha (output, input);
  printOutput (output);
  printf ("Hit any key to contine...");
  getchar ();

  printf ("Displaying the Reverse order\n\n");
  arrangeReverse (output, input);
  printOutput (output);
  printf ("Hit any key to contine...");
  getchar ();

  printf ("Displaying the Opposite ordered lines\n\n");
  arrangeOpposite (output, input);
  printOutput (output);
  printf ("Hit any key to contine...\n");
  getchar ();
}

/*
*/
void printOutput (char buffer[MAX_LINES][MAX_CHAR+1])
{
  int i;

  /* display the total number of lines the user
     entered */
  for (i = 0; i < total_lines_of_input; i++)
  {
        printf ("%s\n", buffer[i]);
  }
  printf ("\n");
}

#ifdef IF_USING_KEYBOARD
/*
  Get up to 50 lines from stdin stream that are at max 80 characters long.
   If a line begins with the enter key, terminate input from stdin.
*/
void getInput (char buffer[MAX_LINES][MAX_CHAR+1])
{
  int i,j,done = FALSE;
  char ch;

  /* get 50 lines of input or until the user types 'ENTER' on the first character
     of the first line */
  for (i = 0; (i < MAX_LINES) && (!done); i++)
  {
    /* get 80 characters unless the user types 'ENTER' */
    for( j = 0; (j < MAX_CHAR) &&  ((ch = getchar()) != EOF) && (ch != '\n'); j++ )      
    {
      /* if the user has typed 'ENTER' set done to TRUE and exit the for loops */
      if (j == 0 &&  (((ch = getchar()) != EOF) || (ch != '\n'))) done = TRUE;
      buffer[i][j] = (char) ch;
    }
    buffer[i][j] = '\0'; /* terminate the string */
  }
  total_lines_of_input = j;
}
#else

void getInput (char buffer[MAX_LINES][MAX_CHAR+1])
{
      strcpy (buffer[0], "All in the golden afternoon");
      strcpy (buffer[1], "Full leisurely we glide;");
      strcpy (buffer[2], "For both our oars, with little skill,");
      strcpy (buffer[3], "By little arms are plied.");
      total_lines_of_input = 4;
}
#endif

void  arrangeAlpha (char destination[MAX_LINES][MAX_CHAR+1], char source[MAX_LINES][MAX_CHAR+1])
{
      char line[MAX_CHAR+1],        /* input line used for strtok of source line */
           editline[MAX_CHAR+1],    /* input line that keeps words that are not the
                                                     smallest until no words remain */
             *smallestword,
             *token;
      int i,
            j,
            count,                     /* current word count in the line */
            smallestwordPos;           /* position used to tell removeWord() the word
                                                      count in the editline to be removed */

      for (i = 0; i < total_lines_of_input; i++)
      {
            /* initialize the string */
            for (j = 0; j < MAX_CHAR+1; j++)
            {
                  destination[i][j] = '\0';
            }

            /* get copies of the current source line */
            strcpy (line, source[i]);
            strcpy (editline, source[i]);

            /* examine each word in line and get the smallest word,
               save the smalllest word in "smallestword" and remove
               the smallest word from "editline" using removeWord()
               and "smallestwordPos" */
            for (j = 0; j < getWordCount(source[i]); j++)
            {
                  token = " ";
                  count = 1;
                  smallestwordPos = 0;
                  /* get the first word */
                  smallestword = strtok (line, " \n");
                  while (token != NULL)
                  {
                        /* get the next word */
                        token = strtok (NULL, " \n");
                        if (token != NULL)
                        {
                            /* if the next word is smaller (alphabetically)
                               than the second word, exchange them */
                              if (stricmp (smallestword, token) > 0)
                              {
                                    strcpy (smallestword, token);
                                    smallestwordPos = count;
                              }
                              count++;
                        }
                  }
                  strcat (destination[i], smallestword);
                  strcat (destination[i], " ");

                  /* take out the smallest word because we
                   have already added it to the alphbetised
                     string */
                  removeWord (editline, smallestwordPos);
                  strcpy (line, editline);
            }
      }
}


void arrangeReverse (char destination[MAX_LINES][MAX_CHAR+1], char source[MAX_LINES][MAX_CHAR+1])
{
      int i = 0, j;

      for (j = total_lines_of_input - 1; j >= 0; j--)
      {
            strcpy (destination[i], source[j]);
            i++;
      }
}

void arrangeOpposite (char destination[MAX_LINES][MAX_CHAR+1], char source[MAX_LINES][MAX_CHAR+1])
{
      char *token,string1[MAX_CHAR+1],string2[MAX_CHAR+1];
      int i,j;

      /* keep processing lines for all the lines the user entered */
      for (i = 0; i < total_lines_of_input; i++)
      {
            /* initialize the strings */
            for (j = 0; j < MAX_CHAR+1; j++)
            {
                  string1[j] = '\0';
                  string2[j] = '\0';
            }

            /* get the first word */
            token = strtok (source[i], " \n");
            /* copy it to the first string buffer */
            strcpy (string1, token);
            /* keep getting words until there are no more words */
            while (token != NULL)
            {
                  /* get the next word */
                  token = strtok (NULL, " \n");
                  /* make sure we don't try to save data when
                     token is at the end of the string */
                  if (token != NULL)
                  {
                        /* save the next word to the second string buffer */
                        strcpy (string2, token);
                        /* add a space to the string */
                        strcat (string2, " ");
                        /* copy the other words to the second string buffer */
                        strcat (string2, string1);
                        /* copy the string in reverse order to the first string buffer */
                        strcpy (string1, string2);
                  }
            }
            /* copy the reversed string to the destination array */
            strcpy (destination[i], string1);
      }
}

/* count the number of words in a line and return the total */
int getWordCount (char string[MAX_CHAR+1])
{
      char *token,temp[MAX_CHAR+1];
      int count = 0;

      /* use a temporary string because strtok will
         overwrites any string it tokens */
      strcpy (temp, string);

      if ((token = strtok (temp, " \n")) == NULL) return 0;
      while (token != NULL)
      {
            token = strtok (NULL, " \n");
            count++;
      }
      return count;
}

/* remove a word from a string concatenating any
   words after the word that is removed;
   based on a zero starting point for the position */
void removeWord (char line[MAX_CHAR+1], int pos)
{
      char *token,string[MAX_CHAR+1];
      int currentPos = 0,i;

      for (i = 0; i < MAX_CHAR+1; i++) string[i] = '\0';

      if ((token = strtok (line, " \n")) == NULL) return;
      while (token != NULL)
      {
            /* if the current word is not the word to
               be removed, add it to the string array */
            if (currentPos != pos)
            {
                  strcat (string, token);
                  token = strtok(NULL, " \n");
                  if (token != NULL) strcat (string, " ");
            }
            else token = strtok(NULL, " \n");
            currentPos++;
      }
      /* copy the string array which has all of the
         words except the one at pos to line */
      strcpy (line, string);
}


Avatar of yllee

ASKER

Hello Kinkajou,

Thank you very very much for your help.

Just a typing mistake for question 2's result.


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

#define True     1
#define False    0

#define MAXCHAR  128
#define FILENAME "C:\\temp\\a.txt"


struct WORD {
    char *pWord;
    WORD *pPrevWord;
    WORD *pNextWord;
};

WORD *CrackWord(char *buff);
WORD *NewWord(char *pStr);
void AddWord(WORD **ppHead, WORD *pNew, int Sort, int Reverse);
WORD *MergeWord(WORD **ppHead);

int SortWord = True;    /* you can change this varible */
int SortLine = True;
int ReverseWord = True;
int ReverseLine = True;

void main()
{
    WORD *pHead, *pTemp;
    FILE* fp;
    char buff[MAXCHAR];

    pHead = pHead->pNextWord = pHead->pPrevWord = NULL;
        if(!(fp=fopen(FILENAME, "rt"))) {
          printf("Can't open file %s.\n", FILENAME);
          return;
      }
      printf("\n\n");
      while(!feof(fp)) {
          if(!fgets(buff, MAXCHAR, fp))
            break;

          printf(buff);
          pTemp = CrackWord(buff);
          if(!pTemp)
            continue;
          AddWord(&pHead, MergeWord(&pTemp), SortLine, ReverseLine);
    }
    printf("\n\n");
    while(pHead) {
        printf("%s\n", pHead->pWord);
      pHead = pHead->pNextWord;
    }

    fclose(fp);
}

WORD *CrackWord(char *pBuff)
{
    WORD *pHead;
    char buff[MAXCHAR];

    pHead = pHead->pNextWord = pHead->pPrevWord = NULL;
    while(*pBuff) {
      while((*pBuff == ' ') || (*pBuff == '\t'))
          pBuff++;
      sscanf(pBuff, "%s", buff);
      pBuff += strlen(buff) + 1;
      AddWord(&pHead, NewWord(buff), SortWord, ReverseWord);
    }
    return pHead;
}

void AddWord(WORD **ppHead, WORD *pNew, int Sort, int Reverse)
{
    WORD *pHead, *pTemp;
    pHead = *ppHead;
    if(!pHead) {
      *ppHead = pNew;
      return;
    }
    if(Sort) {
      if(Reverse) {
          while(*ppHead) {
            if(strcmp((*ppHead)->pWord, pNew->pWord) < 0) {
                if((*ppHead)->pPrevWord) {
                  pTemp = (*ppHead)->pPrevWord;
                  (*ppHead)->pPrevWord = pNew;
                  pNew->pNextWord = *ppHead;
                  pTemp->pNextWord = pNew;
                  pNew->pPrevWord = pTemp;
                }
                else {
                  (*ppHead)->pPrevWord = pNew;
                  pNew->pNextWord = *ppHead;
                  pHead = pNew;
                }
                *ppHead = pHead;
                  return;
            }
            *ppHead = (*ppHead)->pNextWord;
          }
      }
      else {
          while(*ppHead) {
            if(strcmp((*ppHead)->pWord, pNew->pWord) > 0) {
                if((*ppHead)->pPrevWord) {
                  pTemp = (*ppHead)->pPrevWord;
                  (*ppHead)->pPrevWord = pNew;
                  pNew->pNextWord = *ppHead;
                  pTemp->pNextWord = pNew;
                  pNew->pPrevWord = pTemp;
                }
                else {
                  (*ppHead)->pPrevWord = pNew;
                  pNew->pNextWord = *ppHead;
                  pHead = pNew;
                }
                *ppHead = pHead;
                return;
            }
            *ppHead = (*ppHead)->pNextWord;
          }
      }
    }
    *ppHead = pHead;
    while((*ppHead)->pNextWord)
      *ppHead = (*ppHead)->pNextWord;

    (*ppHead)->pNextWord = pNew;
    pNew->pPrevWord = *ppHead;
    *ppHead = pHead;
}

WORD *NewWord(char *pStr)
{
    WORD *pTemp;

    if(!(pTemp = (WORD*)malloc(sizeof(WORD)))) {
      printf("Can't allocate memory.\n");
      return NULL;
    }
    if(!(pTemp->pWord = (char*)malloc(strlen(pStr)))) {
      printf("Can't allocate memory.\n");
      free(pTemp);
      return NULL;
    }
    strcpy(pTemp->pWord, pStr);
    pTemp->pPrevWord = NULL;
    pTemp->pNextWord = NULL;

    return pTemp;
}

WORD *MergeWord(WORD **ppHead)
{
    char buff[MAXCHAR];

    strcpy(buff, "");
    while(*ppHead) {
      strcat(buff, (*ppHead)->pWord);
      strcat(buff, " ");
      if(!(*ppHead)->pNextWord) {
          free(*ppHead);
          break;
        }
        *ppHead = (*ppHead)->pNextWord;
        free((*ppHead)->pPrevWord);
    }
    *ppHead = (*ppHead)->pNextWord = (*ppHead)->pPrevWord = NULL;

    return NewWord(buff);
}
Avatar of yllee

ASKER

Hello Kinkajou,

Thank you very much for your source code.  However, why I can't modify it in order to read input from keyboard as specifie in the question?

I did try to modify, it only read in one line and only reproduce the single together with others funny characters.

You can send your answer directly to my personal email : yllee@po.pacific.net.sg.
I hope I can get your answer as soon as possible.