The program I am writing is supposed to read in a txt file and then align the txt depending on the number of characters per line that the user has specified. Since there aren't any limitations to the length of the text it has to be represented using a dynamic data structure. I'm using a Linked list and the professor wants us to read the file in and store each word as a string. The problem I am having is that we are also supposed to be able to account for multiple paragraphs which are denoted by two '\n's. The program that I have written prints out the text properly but isn't able to detect the paragraphs so the text gets printed out with all the paragraphs combined together. I need them to print out in a seperated fashion. My code is posted below, any help would be appreciated. This is my first class involving C programming so some sample code would be helpful.

My Code:

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


/*This is where the nodes are created*/
struct node
{
  char *word;
  struct node *next;
};

/*Variable declaration for pointers*/
struct node *alist = NULL;
struct node *end = NULL;
struct node *begin = NULL;
struct node *aPtr = NULL;
struct node *tempPtr = NULL;

void LinkedList(struct node *j, struct node **last);
void readfile(int numchar);
void freeMemory();
void printList(int numchar);



int main()
{
  /* This variable is for the user specified number of characters per line*/
  int cPerLine = 0;

  printf("Enter how many characters you want per line between 55 and 80.\n");
  scanf("%d", &cPerLine);
  readfile(cPerLine);
  printList(cPerLine);
  freeMemory();
  return 0;
}

void readfile(int numchar)
{

  FILE *filePtr = NULL;
  char c1, c2;
  char *String = malloc(30*sizeof(char));
  char filename[20];

  printf("Enter the name of the file containing your txt.\n");
  scanf("%s", filename);
  if((filePtr = fopen(filename, "r")) == NULL)
  {
    printf("File can't be opened\n");
    exit(1);
  }
  else
  filePtr = fopen(filename, "r");
  fscanf(filePtr, "%s", String);
  alist = (struct node *)malloc(sizeof(struct node));
  alist->word = String;
  alist->next = NULL;
  end = alist;

  while(!feof(filePtr))
  {
   String = malloc(30*sizeof(char));
   fscanf(filePtr, "%s", String);
   end->next = (struct node *)malloc(sizeof(struct node));
   end = end->next;
   end->word = String;
   end->next = NULL;
   }
   fclose(filePtr);
   printf("\nThe Text is:  \n\n");
}

/*This method is actually printing the stored txt
  from the list with the proper justification
  and characters per line*/
void printList(int numchar)
{
  end = alist;
  aPtr = alist;
  begin = alist;
  tempPtr = begin;

  while(begin->next != NULL)
  {
   int numSpace[80] = {};
   int NumWSpace = 0;/*This variable keeps track of the spaces within a line*/
   int charLine = 0;
   int leftOverSpace = 0;/*This variable is used to determine leftover space so that it can be filled with spaces*/
   int counter = 0;
   int finalLine = 0;
   int j = 0;
   int i = 0;

   charLine = strlen(end->word)+1;
   counter = 1;
   end = end->next;

   while(charLine+strlen(end->word)+1 < numchar)
   {
     charLine = charLine + strlen(end->word) + 1;
     counter = counter + 1;
     if(end->next != NULL)
     end = end->next;
     else
     {
       finalLine = 1;
     }
   }
   leftOverSpace = numchar - (charLine-1);

   while(leftOverSpace > 0)
   {
     if(NumWSpace < (counter - 1))
     {
       numSpace[NumWSpace] = numSpace[NumWSpace] + 1;
       leftOverSpace = leftOverSpace - 1;
       NumWSpace = NumWSpace + 1;
     }
     else
     NumWSpace = 0;
   }


 /*This loop will print out the words for the line it is on*/

   for( i = 1; i <= counter; i++)
   {
     if(i , counter)
     {
       printf("%s ", aPtr->word);
       for(j = 1; j <= numSpace[i-1]; j++)
       {
         printf(" ");
       }
     }
     else if(i = counter)
     {
       printf("%s\n", aPtr->word);
     }
     if(aPtr->next != NULL)
     aPtr = aPtr->next;
   }
   if(aPtr->next != NULL)
     end = aPtr;
   if(end->next == NULL)
     begin = end;
   printf("\n");
}
}


void freeMemory()
{

   end = alist;
   while(end->next != NULL)
   {
     end = end->next;
   }
   while(alist != NULL)
   {
     if(end == alist)
     {
       free(alist->word);
       free(alist);
       alist = NULL;
       end = NULL;
       aPtr = NULL;
     }
     else
     {
       aPtr = alist;
       while(aPtr->next != end)
       aPtr = aPtr->next;
       free(end->word);
       free(end);
       end = aPtr;
     }
   }
}

Recommended Answers

All 6 Replies

The problem you are having with paragraphs is that fscanf is a bit too heavy a hammer for your needs:
s Matches a sequence of bytes that are not white-space characters (http://opengroup.org/onlinepubs/007908775/xsh/fscanf.html)
What you really want is to read line by line. That way, when you see an empty line, you can retain the information. Try using fgets (there is a gets function, but it is dangerous because it allows buffer overflow) See http://www.opengroup.org/onlinepubs/009695399/functions/fgets.html ... and be sure to use the n parameter to avoid buffer overflow.

The problem you are having with paragraphs is that fscanf is a bit too heavy a hammer for your needs:
s Matches a sequence of bytes that are not white-space characters (http://opengroup.org/onlinepubs/007908775/xsh/fscanf.html)
What you really want is to read line by line. That way, when you see an empty line, you can retain the information. Try using fgets (there is a gets function, but it is dangerous because it allows buffer overflow) See http://www.opengroup.org/onlinepubs/009695399/functions/fgets.html ... and be sure to use the n parameter to avoid buffer overflow.

Ok, I'm not really sure how to use fgets , I checked the link that you provided but it didn't help me much, is there anyway you could post on how I would need to restructure my code so that fgets could be utilized.

You use it very much the same way you use fscanf , but instead of words, you get lines. Once you have a line, you need to break it apart into words, which you can do with sscanf . The advantage of getting a line at a time is that you get to see whether the line is empty. Thus, for this file:

line1
line2

line4


line7

you would see in sequence "line1\n", "line1\n", "\n", "line4\n", "\n", "\n", "line7\n" (eof) You can check if '\n' is the first character on the line (which will make it the last and only character) and if so, you print/write out the wrapped words for the paragraph then a newline.

the program ought to look like

/*declarations*/
struct node {char* word, node* next};
/** read lines, split them into words, add words to a linked list. 
  * Return the list when you see a newline or eof 
  */
node* readParagraph(file* openFilePointer);
/** print words from the supplied list as lines wrapped on or before lineLength */
void printWrapped(node* list, int lineLength);

/*definitions: Left as an exercise*/

int main() {
  /*get file name and open it OR fail: return 1 */
  /* get lineLength */
  while not eof {
    wordsInParagraph = readParagraph(theFilePointer);
    printWrapped(wordsInParagraph,lineLength);
  }
  return 0;
}

Daniweb and I became disconnected while I was trying to finish editing my post. The result is that the code for 'program ought to look like this' is not syntactically correct. Line 15 should look like while(/*not eof*/) {

please i need d source code for conversion of lowercase characters to uppercase in c programming language

please i need d source code for conversion of lowercase characters to uppercase in c programming language

You should have read this [thread=78060]This thread[/thread] before posting. Please read it now. Then start your own thread for your own question.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.